我正在尝试找到一个解决这个问题的方法:
给定一个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
};"foreach seq in seqs“..生成{#0,#1,#2}或{#0,#2,#3}
我应该选择..。
。。一些聪明的IEqualityComparer
。。一些我还没弄明白的巧妙的LINQ组合-- groupby,sequenceequal……?
。。一些seq->HashSet内容
。。还有什么不好。任何事都能帮上忙
我可以通过好的老程序来解决这个问题,但是灵感总是值得欣赏的。
发布于 2011-01-17 06:13:07
以下是digEmAll的答案的一个稍微简单一点的版本:
var result = seqs.Select(x => new HashSet<int>(x))
.Distinct(HashSet<int>.CreateSetComparer());考虑到您希望将元素作为集合处理,您应该以这种方式开始使用它们,IMO。
当然,如果你想在返回的序列中保持顺序,这不会有什么帮助,你只是不关心返回哪个相等的集合……上面的代码将返回一个在每个序列中不再有任何排序的IEnumerable<HashSet<int>>。(也不能保证返回集合的顺序,尽管不以先见先返回的方式返回它们会很奇怪。)
这不太可能是不够的,但如果你能给出你真正需要实现的更多细节,这将使帮助变得更容易。
正如注释中所指出的,这也将假设在每个原始源数组中没有副本...或者至少,它们是不相关的,所以你很高兴将{1}和{ 1,1,1,1}平等对待。
发布于 2011-01-17 06:06:08
为作业使用正确的集合类型。您真正想要的是带有一个相等比较器的ISet<IEnumerable<int>>,它将忽略IEnumerable的顺序。
发布于 2011-01-17 06:10:34
编辑:
你可以通过构建你自己的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],因此基本上这两个列表必须包含相同的元素,并且出现的次数相同。
https://stackoverflow.com/questions/4708362
复制相似问题