2012-09-11 7 views

risposta

49

Se non avete a cuore le prestazioni, si potrebbe provare:

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

ma vorrei provare questa prima:

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

funziona come un fascino. Dato che sei il primo rispondente, ho contrassegnato il tuo come risposta. Grazie. – wahaha

+0

Non è possibile utilizzare 'a' entrambi come lista e nella lambda. 'a.Any (a => b.Contains (a))'. Suggerirei di usare un gruppo di metodi invece 'a.Any (b.Contains)' – radbyx

9

È possibile Intersect le due liste:

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

Ho profilato Justin due soluzioni. a.Any(a => b.Contains(a)) è il più veloce.

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

Scrivo un metodo più veloce perché può impostare quello piccolo da impostare. Ma lo provo in alcuni dati che a volte è più veloce di Intersect ma a volte Intersect digiuna il mio codice.

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

l'Intersect chiamate Set che non sono controlla la seconda dimensione e questo è il codice del 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; 

La differenza di due metodi è il mio metodo usare HashSet e controllare il conteggio e Intersect uso set che è più veloce di HashSet. Non guerreggiamo le sue prestazioni.

La prova:

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

Io uso questo per contare:

 int cnt = 0; 

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

A Count non viene richiesto. Questo è un codice imperativo molto inefficiente. –

+0

Un po 'più di spiegazione potrebbe essere utile per questa risposta, ad esempio perché si è scelto di utilizzare un conteggio anziché un valore booleano. Questo * fa * però ha fatto il lavoro. – Taegost

Problemi correlati