的IEnumerable <IEnumerable的<int>的&GT; - 没有重复的IEnumerable <int> s </int> </ienumerable <int>

时间:2011-01-16 22:00:28

标签: c# linq ienumerable

我正在尝试找到解决此问题的方法:

给定IEnumerable&lt; IEnumerable的&LT; INT&GT;&GT;我需要一个返回输入的方法/算法,但是在几个IEnmerable&lt; INT&GT;使用相同的元素,每个巧合/组只返回一个。

离。

    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东西

..什么不是。一切都会有所帮助

我将能够通过优秀的编程来解决它,但总是能够激发灵感。

3 个答案:

答案 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],因此基本上两个列表必须包含相同的元素且出现次数相同。