C# 如何检查列表 A 包含列表 B 中的任何值?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12376437/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to check list A contains any value from list B?
提问by wahaha
List A:
清单 A:
1, 2, 3, 4
List B:
名单乙:
2, 5
How to check if list A contains any value from list B?
如何检查列表 A 是否包含列表 B 中的任何值?
e.g. something like A.contains(a=>a.id = B.id)?
例如像 A.contains(a=>a.id = B.id) 之类的东西?
采纳答案by Justin Niessner
If you didn't care about performance, you could try:
如果你不关心性能,你可以尝试:
a.Any(item => b.Contains(item))
// or, as in the column using a method group
a.Any(b.Contains)
But I would try this first:
但我会先试试这个:
a.Intersect(b).Any()
回答by radbyx
I've profiled Justins two solutions. a.Any(a => b.Contains(a))is fastest.
我已经介绍了贾斯汀的两种解决方案。a.Any(a => b.Contains(a))是最快的。
using System;
using System.Collections.Generic;
using System.Linq;
namespace AnswersOnSO
{
public class Class1
{
public static void Main(string []args)
{
// How to check if list A contains any value from list B?
// e.g. something like A.contains(a=>a.id = B.id)?
var a = new List<int> {1,2,3,4};
var b = new List<int> {2,5};
var times = 10000000;
DateTime dtAny = DateTime.Now;
for (var i = 0; i < times; i++)
{
var aContainsBElements = a.Any(b.Contains);
}
var timeAny = (DateTime.Now - dtAny).TotalSeconds;
DateTime dtIntersect = DateTime.Now;
for (var i = 0; i < times; i++)
{
var aContainsBElements = a.Intersect(b).Any();
}
var timeIntersect = (DateTime.Now - dtIntersect).TotalSeconds;
// timeAny: 1.1470656 secs
// timeIn.: 3.1431798 secs
}
}
}
回答by lindexi
I write a faster method for it can make the small one to set. But I test it in some data that some time it's faster that Intersect but some time Intersect fast that my code.
我写了一个更快的方法,它可以使小的设置。但是我在一些数据中对其进行了测试,有时它比 Intersect 更快,但有些时候 Intersect 比我的代码快。
public static bool Contain<T>(List<T> a, List<T> b)
{
if (a.Count <= 10 && b.Count <= 10)
{
return a.Any(b.Contains);
}
if (a.Count > b.Count)
{
return Contain((IEnumerable<T>) b, (IEnumerable<T>) a);
}
return Contain((IEnumerable<T>) a, (IEnumerable<T>) b);
}
public static bool Contain<T>(IEnumerable<T> a, IEnumerable<T> b)
{
HashSet<T> j = new HashSet<T>(a);
return b.Any(j.Contains);
}
The Intersect calls Setthat have not check the second size and this is the Intersect's code.
Set没有检查第二个大小的 Intersect 调用,这是 Intersect 的代码。
Set<TSource> set = new Set<TSource>(comparer);
foreach (TSource element in second) set.Add(element);
foreach (TSource element in first)
if (set.Remove(element)) yield return element;
The difference in two methods is my method use HashSetand check the count and Intersectuse setthat is faster than HashSet. We dont warry its performance.
两种方法的区别在于我的方法使用HashSet和检查计数和Intersect使用set比HashSet. 我们不担心它的性能。
The test :
考试 :
static void Main(string[] args)
{
var a = Enumerable.Range(0, 100000);
var b = Enumerable.Range(10000000, 1000);
var t = new Stopwatch();
t.Start();
Repeat(()=> { Contain(a, b); });
t.Stop();
Console.WriteLine(t.ElapsedMilliseconds);//490ms
var a1 = Enumerable.Range(0, 100000).ToList();
var a2 = b.ToList();
t.Restart();
Repeat(()=> { Contain(a1, a2); });
t.Stop();
Console.WriteLine(t.ElapsedMilliseconds);//203ms
t.Restart();
Repeat(()=>{ a.Intersect(b).Any(); });
t.Stop();
Console.WriteLine(t.ElapsedMilliseconds);//190ms
t.Restart();
Repeat(()=>{ b.Intersect(a).Any(); });
t.Stop();
Console.WriteLine(t.ElapsedMilliseconds);//497ms
t.Restart();
a.Any(b.Contains);
t.Stop();
Console.WriteLine(t.ElapsedMilliseconds);//600ms
}
private static void Repeat(Action a)
{
for (int i = 0; i < 100; i++)
{
a();
}
}
回答by Jan
I use this to count:
我用这个来计算:
int cnt = 0;
foreach (var lA in listA)
{
if (listB.Contains(lA))
{
cnt++;
}
}
回答by Atanas Atanasov
Sorry, if this is irelevant, but will return list with matches using FindAll() in case you need this:
抱歉,如果这无关紧要,但会在需要时使用 FindAll() 返回匹配项列表:
private bool IsContain(string cont)
{
List<string> ListToMatch= new List<string>() {"string1","string2"};
if (ListToMatch.ToArray().Any(cont.Contains))
{
return false;
}
else
return true;
}
And usage:
和用法:
List<string> ListToCheck = new List<string>() {"string1","string2","string3","string4"};
List<string> FinalList = ListToCheck.FindAll(IsContain);
The final list contains only the matched elements string1 and string2 from list to check. Can easy be switched to int List.
最终列表仅包含要检查的列表中匹配的元素 string1 和 string2。可以轻松切换到 int 列表。
回答by Kerman
回答by Pperez
You can check if a list is inside of another list with this
您可以使用此检查列表是否在另一个列表中
var list1 = new List<int> { 1, 2, 3, 4, 6 };
var list2 = new List<int> { 2, 3 };
bool a = list1.Any(c => list2.Contains(c));

