Liste A:
1, 2, 3, 4
Liste B:
2, 5
Comment vérifier si la liste A contient une valeur de la liste B?
par exemple. quelque chose comme A.contains (a => a.id = B.id)?
Si vous ne vous souciez pas de la performance, vous pouvez essayer:
a.Any(item => b.Contains(item))
// or, as in the column using a method group
a.Any(b.Contains)
Mais je voudrais essayer ceci en premier:
a.Intersect(b).Any()
J'ai présenté deux solutions à Justins.a.Any(a => b.Contains(a))
est le plus rapide .
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)?
List<int> a = new List<int> {1,2,3,4};
List<int> b = new List<int> {2,5};
int times = 10000000;
DateTime dtAny = DateTime.Now;
for (int i = 0; i < times; i++)
{
var aContainsBElements = a.Any(b.Contains);
}
var time = (DateTime.Now - dtAny).TotalSeconds;
DateTime dt2 = DateTime.Now;
for (int i = 0; i < times; i++)
{
var aContainsBElements = a.Intersect(b).Any();
}
var time2 = (DateTime.Now - dt2).TotalSeconds;
// time1: 1.1470656 secs
// time2: 3.1431798 sec
}
}
}
Vous pouvez Intersect
les deux listes:
if (A.Intersect(B).Any())
J'utilise ceci pour compter:
int cnt = 0;
foreach (var lA in listA)
{
if (listB.Contains(lA))
{
cnt++;
}
}
J'écris une méthode plus rapide pour que le petit soit paramétré. Mais je teste dans certaines données qu'il est parfois plus rapide que Intersect, mais que Intersect rapidement que mon code.
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);
}
Les appels d'intersection Set
qui n'ont pas vérifié la deuxième taille et il s'agit du code de l'intersection.
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;
La différence entre deux méthodes est que ma méthode utilise HashSet
et vérifie le nombre et Intersect
utilise set
qui est plus rapide que HashSet
. Nous ne mettons pas en garde ses performances.
Le 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();
}
}
Désolé, si cela n'a pas d'importance, mais nous renverrons la liste avec les correspondances utilisant FindAll () au cas où vous en auriez besoin:
private bool IsContain(string cont)
{
List<string> ListToMatch= new List<string>() {"string1","string2"};
if (ListToMatch.ToArray().Any(cont.Contains))
{
return false;
}
else
return true;
}
Et utilisation:
List<string> ListToCheck = new List<string>() {"string1","string2","string3","string4"};
List<string> FinalList = ListToCheck.FindAll(IsContain);
La liste finale ne contient que les éléments correspondants string1 et string2 from list à vérifier . Peut facilement être basculé sur int List.