假设我有任意数量的列表
List<int> List1 = new List<int>();
List<int> List2 = new List<int>();
List<int> ListN = new List<int>();
我怎样才能得到一个最终列表,它只包含每个列表中存在的那些元素。
我最初用很多循环来做到这一点。然而我并不满意。由于我对 LINQ 的了解有限,我认为这应该很容易做到,但我什至不知道从哪里开始。
有没有其他方法可以做到这一点,最好是使用 LINQ。
假设我有任意数量的列表
List<int> List1 = new List<int>();
List<int> List2 = new List<int>();
List<int> ListN = new List<int>();
我怎样才能得到一个最终列表,它只包含每个列表中存在的那些元素。
我最初用很多循环来做到这一点。然而我并不满意。由于我对 LINQ 的了解有限,我认为这应该很容易做到,但我什至不知道从哪里开始。
有没有其他方法可以做到这一点,最好是使用 LINQ。
List<List<int>> lists = new List<List<int>>{
List2, ..., ListN
};
IEnumerable<int> result = List1;
foreach(var list in lists){
result = result.Intersect(list);
if(!result.Any()) break;
}
//Use ToList() on result to get List<int>
利用Intersect
var r = List1.Intersect(List2).Intersect(ListN);
例子:
var r = new [] { 1, 2, 3, 4 }
.Intersect(new [] { 2, 3, 4, 5 })
.Intersect(new [] { 3, 4, 5, 6 });
// r now contains 3, 4
文档:http: //msdn.microsoft.com/en-us/library/bb460136.aspx
这是一个扩展方法,它采用列表列表并对所有列表执行交集。与上面相同,但使用起来可能更简单?
public static IEnumerable<T> IntersectAll<T>(
this IEnumerable<T> list,
params IEnumerable<T>[] otherLists
) {
foreach (var otherList in otherLists)
{
list = list.Intersect(otherList);
}
return list;
}
用法:
var r = new [] { 1, 2, 3, 4 }
.IntersectAll(new [] { 2, 3, 4, 5 }, new [] { 3, 4, 5, 6 });
很简单:
var intersection = List1.Intersect(List2).Intersect(List3);
或者,如果您想轻松支持n个列表:
var lists = new List<List<string>>();
lists.Add(new List<string>(new string[] { "Test1", "Test2", "Test3" }));
lists.Add(new List<string>(new string[] { "Test1", "Test2", "Test4" }));
lists.Add(new List<string>(new string[] { "Test1", "Test2", "Test5" }));
lists.Add(new List<string>(new string[] { "Test1", "Test2", "Test6" }));
var aggregate = lists.Aggregate((x, y) => x.Intersect(y).ToList());
虽然您可以使用 LINQ 的方法,但这将导致不断地获取当前的交叉点并用这些项目Intersect
重新填充新的交叉点。HashSet
通过使用您自己的显式HashSet
,您可以更有效地获得 N 个序列的交集:
public static IEnumerable<T> intersectAll<T>(IEnumerable<IEnumerable<T>> source)
{
using (var iterator = source.GetEnumerator())
{
if (!iterator.MoveNext())
return Enumerable.Empty<T>();
var set = new HashSet<T>(iterator.Current);
while (iterator.MoveNext())
set.IntersectWith(iterator.Current);
return set;
}
}