使用LINQ选择具有相同子集合的项目

时间:2010-09-08 19:05:09

标签: c# linq

以下是伪案例:

class parent{
   string name; //Some Property
   List<int> myValues;

   .......
}
........
//Initialize some parent classes

List<parent> parentList = new List<parent>();
parentList.add(parent123); //parent123.myValues == {1,2,3}
parentList.add(parent456); //parent456.myValues == {4,5,6}
parentList.add(parentMatch); //parentMatch.myValues == {1,2,3}

我的目标是检索一个父对象列表的查询    myValues列表是等价的。在这种情况下,它将返回parent123和parentMatch。

3 个答案:

答案 0 :(得分:3)

因此,如果实施GroupBy,您可以将逻辑包起来并使用IEqualityComparer

class IntegerListComparer : IEqualityComparer<List<int>>
{
    #region IEqualityComparer<List<int>> Members

    public bool Equals(List<int> x, List<int> y)
    {
        //bool xContainsY = y.All(i => x.Contains(i));
        //bool yContainsX = x.All(i => y.Contains(i));
        //return xContainsY && yContainsX;
        return x.SequenceEqual(y);
    }

    public int GetHashCode(List<int> obj)
    {
        return 0;
    }

    #endregion
}

这样称呼:

var results = list
    .GroupBy(p => p.MyValues, new IntegerListComparer())
    .Where(g => g.Count() > 1)
    .SelectMany(g => g);

答案 1 :(得分:1)

非常愚蠢的解决方案:

var groups = list.GroupBy(p => string.Join(",", p.list.Select(i => i.ToString()).ToArray()))
                    .Where(x => x.Count() > 1).ToList();

结果:

包含父对象的IEnumerable个组,其中列表具有相同的int(以相同的顺序)。

如果您需要按任意顺序匹配元素列表(例如1,2,3 == 3,1,2),只需将p.list更改为p.list.OrderBy(x => x)

另外,如果您的目标是框架4.0,则可以避免ToArrayToString


修改

添加了过滤单次出现组的位置。

现在,如果你有这些父母:

parent  A  1,2,3
parent  B  1,2,3
parent  C  1,2,3
parent  D  4,5,6
parent  E  4,5,6
parent  F  7,8,9

它返回:

(A,B,C) - (D,E)

答案 2 :(得分:0)

试试这个:

var matches = (from p1 in parentList
               from p2 in parentList
               let c1 = p1.myValues
               let c2 = p2.myValues
               where p1 != p2 &&
                     c1.All(child => c2.Contains(child)) &&
                     c2.All(child => c1.Contains(child))
               select p1).Distinct();