合并多个列表,但仅保留在所有列表中找到的值
本文关键字:列表 保留 合并 | 更新日期: 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);