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

本文关键字:列表 保留 合并 | 更新日期: 2023-09-27 18:37:06

如果我有数组:

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

什么方法可以帮助我只保留在所有列表中找到的值。在这个例子中,我想以{2,3}结束,因为这两个值可以在所有列表中找到。

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

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

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

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

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。 它将在整个过程中重复使用相同的一个。

可以使用 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);

其他人已经提出了良好和有效的解决方案。根据他们的回答,我提出这个建议:

 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);