从IEnumerable <ienumerable <t>&gt;中删除重复的IEnumerable <t>

时间:2017-08-30 06:32:35

标签: c# linq

如何从给定的集合集合中删除重复内容?没有考虑到订单。

例如。

IEnumerable<IEnumerable<T>> Collection = [{1,2,3} , {2,1,3}, {1,1,2}, {1,2,2}]

应该是

IEnumerable<IEnumerable<T>> Collection = [{1,2,3} , {1,1,2}, {1,2,2}] // [ {2,1,3}, {1,1,2}, {1,2,2}] is also valid

**编辑**

据我所知,对于IEnumerables E1和E2我可以做这样的事情来找到重复项:

bool equal = (E1.Count() == E2.Count() && (!E1.Except(E2).Any() || !E2.Except(E1).Any()))

if(equal)
{
    //Do something
}

然而,如何为

做类似的事情
IEnumerable<IEnumerable<T>>

1 个答案:

答案 0 :(得分:1)

诀窍是建立一个新的列表,只包含唯一的项目。你的支票呢 不适用于所有边缘情况(例如,您的检查对{1, 1, 2} == {1, 2, 3}成功,因为值类型只能比较相等而不是同一性)。

最简单的方法是对集合进行排序,而不是使用Enumerable.SequenceEqual

public static class Helper
{
   public static IEnumerable<IEnumerable<int>> Unique(this IEnumerable<IEnumerable<int>> source)
   {
      var list = new List<List<int>>(); // sorted reference list.

      foreach (var toCompare in source)
      {
         var toComp = toCompare.OrderBy(x => x).ToList(); // prevent multiple enumerations.
         if (!list.Any(item => toComp.SequenceEqual(item)))
         {
            list.Add(toComp);
            yield return toCompare; // return the unsorted one!
         }
      }
   }
}

用法

var unique = collection.Unique();

上面的代码如何工作:

我们保留所有返回项目的引用列表,但是引用列表已排序。然后我们枚举源列表,对每个项进行排序并检查它是否已经在我们的引用列表中,如果不是,我们将已排序的项添加到引用列表中,并yield return未分类的原始项。