如何使用LINQ查找列表中包含其他列表中成员最多的所有项目?

时间:2014-07-31 13:45:57

标签: linq

假设:

class Item {
    public int[] SomeMembers { get; set; }
}

var items = new []
{
    new Item { SomeMembers = new [] { 1, 2 } }, //0
    new Item { SomeMembers = new [] { 1, 2 } }, //1
    new Item { SomeMembers = new [] { 1 } }     //2
}

var secondList = new int[] { 1, 2, 3 };

我需要找到Itemitems的{​​{1}} SomeMember secondList Contains()

在上面的示例中,我希望返回项目0和1,但不能返回2.

我知道我可以用循环或{{1}}之类的东西来做,但似乎必须有一种更优雅或更有效的方式?

1 个答案:

答案 0 :(得分:1)

这可以很容易地写出来:

var result = items.Where(item => item.SomeMembers.Count(secondList.Contains) * 2
                                         >= item.SomeMembers.Length);

或者可能(我无法猜测方法组转换是否有效):

var result = items.Where(item => item.SomeMembers.Count(x => secondList.Contains(x)) * 2
                                         >= item.SomeMembers.Length);

或者把它拉出来:

Func<int, bool> inSecondList = secondList.Contains;
var result = items.Where(item => item.SomeMembers.Count(inSecondList) * 2
                                         >= item.SomeMembers.Length);

如果secondList变大,您应该考虑使用HashSet<int>

编辑:为避免两次评估SomeMembers,您可以创建一个扩展方法:

public static bool MajoritySatisfied<T>(this IEnumerable<T> source,
                                        Func<T, bool> condition)
{
    int total = 0, satisfied = 0;
    foreach (T item in source)
    {
        total++;
        if (condition(item))
        {
            satisfied++;
        }
    }
    return satisfied * 2 >= total;
}

然后:

var result = items.Where(item => item.MajoritySatisfied(secondList.Contains));