2012-09-11 10 views

Respuesta

49

Si no se preocupan por el rendimiento, puede intentar:

a.Any(item => b.Contains(item)) 
// or, as in the column using a method group 
a.Any(b.Contains) 

pero me gustaría probar este primero:

a.Intersect(b).Any() 
+0

funciona como un encanto. Como usted es el primer demandado, marqué el suyo como respuesta. Gracias. – wahaha

+0

No puede usar 'a' como la lista y en la lambda. 'a.Any (a => b.Contains (a))'. Sugeriría utilizar un grupo de métodos en lugar 'a.Any (b.Contains)' – radbyx

9

Puede Intersect las dos listas:

if (A.Intersect(B).Any()) 
11

He perfilado Justins dos soluciones. a.Any(a => b.Contains(a)) es el más rápido.

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 
     } 
    } 
} 
0

Escribo un método más rápido porque puede hacer que el más pequeño se establezca. Pero lo pruebo en algunos datos que algún tiempo es más rápido que se cruzan, pero a veces se cruzan rápidamente con mi código.

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); 
    } 

La Intersección llama Set que no se marque la segunda tamaño y este es el código de la intersección.

 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 diferencia de dos métodos se utilice mi método HashSet y verificar el conteo y el uso Intersectset que es más rápido que HashSet. No nos preocupa su rendimiento.

La prueba:

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(); 
     } 
    } 
0

Lo utilizo para contar:

 int cnt = 0; 

     foreach (var lA in listA) 
     { 
      if (listB.Contains(lA)) 
      { 
       cnt++; 
      } 
     } 
+0

No se solicita un conteo. Este es un código imperativo muy ineficiente. –

+0

Puede necesitar un poco más de explicación para esta respuesta, como por qué eligió usar un conteo en lugar de un valor booleano. Esto * does * hacer el trabajo sin embargo. – Taegost

Cuestiones relacionadas