合并多个列表但仅保留在所有列表中找到的值

时间:2013-10-28 18:24:39

标签: c# linq collections

如果我有阵列:

var list1 = new int[] { 1,2,3,4,5};
var list2 = new int[] { 1,2,3};
var list3 = new int[] { 2,3};

什么方法可以帮助我保持只在所有列表中找到的值。在此示例中,我希望最终得到{2,3},因为在所有列表中都可以找到这两个值。

4 个答案:

答案 0 :(得分:4)

使用Intersect - >通过使用默认的相等比较器来比较值,生成两个序列的集合交集。 (MSDN:http://msdn.microsoft.com/en-us/library/bb460136.aspx

var list = list1.Intersect(list2).Intersect(list3);

答案 1 :(得分:3)

您可以使用此方法获取任意数量序列的交集:

public static IEnumerable<T> IntersectAll<T>(params IEnumerable<T>[] sequences)
{
    if (!sequences.Any())
        return Enumerable.Empty<T>();

    var set = new HashSet<T>(sequences.First());
    foreach (var sequence in sequences.Skip(1))
    {
        set.IntersectWith(sequence);
    }
    return set;
}

请注意,与重复调用LINQ Intersect方法不同,这不会重复重建中间HashSet。它将在整个过程中重复使用。

答案 2 :(得分:1)

您可以像使用LINQ的一部分那样使用Intersect方法:

var result = list1.Intersect(list2).Intersect(list3);

如果你想要一个可以传递任意数量列表的方法,你可以使用它:

public static int[] Process(params int[][] values)
{
    int[] result = values[0];

    foreach (int[] value in values)
    {
        result = result.Intersect(value).ToArray();
    }

    return result;
}

您可以这样称呼它:

var result = Process(list1, list2, list3);

答案 3 :(得分:0)

其他人已经提出了良好和有效的解决方案。基于他们的回答,我提出了这个问题:

 public static class IEnumerableExtension
    {
        public static IEnumerable<T> Intersect<T>(this IEnumerable<T> one, params IEnumerable<T>[] others)
        {
            var result = one;
            foreach (var other in others)
                result = result.Intersect(other);

            return result;
        }
    }

用法如下:

var result = list1.Intersect(list2,list3,...continued to...listn);