如何查找列表中的元素是否在另一个列表中?
我想知道是否可以在第二个列表中找到第一个列表中的至少一个元素。
我可以看到两种方法可以做到这一点。假设我们的列表是:
List<string> list1 = new[] { "A", "C", "F", "H", "I" };
List<string> list2 = new[] { "B", "D", "F", "G", "I" };
第一种方法使用循环:
bool isFound = false;
foreach (item1 in list1)
{
if (list2.Contains(item1))
{
isFound = true;
break;
}
}
第二种方法直接使用 Linq:
bool isFound = list1.Intersect(list2).Any();
第一种方法写起来很长,而且不是很简单/易于阅读。第二个简短而清晰,但性能会很低,尤其是在大型列表上。
什么可能是一种优雅的方式来做到这一点?
I want to know if at least one element in a first list can be found in a second list.
I can see two ways to do it. Let's say our lists are:
List<string> list1 = new[] { "A", "C", "F", "H", "I" };
List<string> list2 = new[] { "B", "D", "F", "G", "I" };
The first approach uses a loop:
bool isFound = false;
foreach (item1 in list1)
{
if (list2.Contains(item1))
{
isFound = true;
break;
}
}
The second one uses Linq directly:
bool isFound = list1.Intersect(list2).Any();
The first one is long to write and not very straightforward/easy-to-read. The second one is short and clear, but performances will be low, especially on large lists.
What may be an elegant way to do it?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
第二个在大型列表上比第一个具有更好的性能。
Intersect
将一个列表的元素放入哈希表中,然后再检查另一个列表的元素的成员资格。The second one has better performance on large lists than the first one.
Intersect
puts the elements of one list into a hash table before checking the other list's elements for membership.当原始版本显然是(最坏情况)O(n*m) 时,批评 LINQ 的性能似乎很奇怪; LINQ 方法我期望在列表上使用
HashSet
,然后使用流式迭代器块 - 因此性能应该为 O(n+m) -即更好。It seems odd to critique the performance of LINQ when the original is clearly (worst case) O(n*m); the LINQ approach would I expect use a
HashSet<T>
on a list, and then use a streaming iterator block - so the performance should be O(n+m) - i.e. better.我认为对于大型列表来说,第二个会更快。由于第一个是 O(list1.Count*list2.Count),而第二个是 O(list1.Count+list2.Count)。但第二个需要更多内存。
linq 的开销通常是手工代码的恒定倍数。我猜第二个比命令式代码最多慢两倍,甚至可能还不到这个速度。它使用
O(list1.Count+list2.Count)
内存,如果您仔细编写代码,内存可以减少到O(Min(list1,list2))
内存使用量同时保持线性性能。此代码在大型列表上应该相对较快:
您可以通过将较小的列表放入哈希集而不是始终使用 list2 来进一步优化此代码。
I think the second one will be faster for large lists. Since the first one is O(list1.Count*list2.Count) whereas the second is O(list1.Count+list2.Count). Second one takes more memory though.
And the overhead of linq is typically a constant multiplication factor over handcrafted code. I'd guess the second one is slower than imperative code by at most a factor of two, probably not even that. It uses
O(list1.Count+list2.Count)
memory which can be cut down toO(Min(list1,list2))
if you carefully write your code for low memory usage whilte retaining linear performance.This code should be relatively fast on large lists:
You can optimize this code further by making the smaller list into a hashset instead of always using list2.
接受的答案很好,但它不适用于 Linq-to-sql,因为没有
Intersect
的映射。在这种情况下,您应该使用:
这会被编译为
WHERE EXSITS
The accepted answer is great, however it does not work with Linq-to-sql, since there's no mapping for
Intersect
.In that case you should use :
This gets compiled to
WHERE EXSITS
这是了解一个列表的元素是否存在于另一个列表中的另一种方法。
This is another way to know if an element of one list exists in another list.