我正在尝试找到解决此问题的方法:
给定IEnumerable< IEnumerable的< INT>>我需要一个返回输入的方法/算法,但是在几个IEnmerable< INT>使用相同的元素,每个巧合/组只返回一个。
离。
IEnumerable<IEnumerable<int>> seqs = new[]
{
new[]{2,3,4}, // #0
new[]{1,2,4}, // #1 - equals #3
new[]{3,1,4}, // #2
new[]{4,1,2} // #3 - equals #1
};
“seqs中的foreach seq”..产生{#0,#1,#2}或{#0,#2,#3}
我可以去..
..一些聪明的IEqualityComparer
..一些聪明的LINQ组合我还没弄明白 - groupby,sequenceequal ..?
..一些seq-&gt; HashSet东西
..什么不是。一切都会有所帮助
我将能够通过优秀的编程来解决它,但总是能够激发灵感。
答案 0 :(得分:7)
以下是digEmAll答案的一个稍微简单的版本:
var result = seqs.Select(x => new HashSet<int>(x))
.Distinct(HashSet<int>.CreateSetComparer());
鉴于您希望将元素视为集合,您应该让它们以IMO开头。
当然,如果你想在返回的序列中保持顺序,这将无济于事,你只是不介意返回相等集合的 ......上面的代码将会返回IEnumerable<HashSet<int>>
,在每个序列中不再有任何排序。 (也不保证返回设置的顺序,尽管它们在首先看到的第一次返回的基础上不返回会很奇怪。)
这不太可能是不够的,但是如果你能提供更多关于你真正需要实现的细节,那将会更容易提供帮助。
如评论中所述,这也将假设每个原始源数组中 中没有重复项<...>或者至少它们是无关紧要的,所以您很乐意对待{ 1}和{1,1,1,1}相同。
答案 1 :(得分:4)
为作业使用正确的集合类型。你真正想要的是ISet<IEnumerable<int>>
使用相等比较器来忽略IEnumerable
的排序。
答案 2 :(得分:3)
<强>编辑:强>
您可以通过构建自己的IEqualityComparer<IEnumerable<int>>
例如:
public class MyEqualityComparer : IEqualityComparer<IEnumerable<int>>
{
public bool Equals(IEnumerable<int> x, IEnumerable<int> y)
{
return x.OrderBy(el1 => el1).SequenceEqual(y.OrderBy(el2 => el2));
}
public int GetHashCode(IEnumerable<int> elements)
{
int hash = 0;
foreach (var el in elements)
{
hash = hash ^ el.GetHashCode();
}
return hash;
}
}
<强>用法:强>
var values = seqs.Distinct(new MyEqualityComparer()).ToList();
<强> N.B。强>
这个解决方案与Jon Skeet给出的解决方案略有不同
他的回答将子列表视为集,因此基本上两个列表如[1,2]
和[1,1,1,2,2]
相同。
这个解决方案没有,即:
[1,2,1,1]
等于[2,1,1,1]
但不等于[2,2,1,1]
,因此基本上两个列表必须包含相同的元素且出现次数相同。