2009-02-26 19 views
40

Ho due IEnumerable<T> s.Unione di due elementi IEnumerable <T> s

Uno si riempie degli ellementi di fallback. Questo conterrà sempre la maggior parte degli elementi. L'altro si riempirà a seconda di alcuni parametri e conterrà probabilmente meno elementi. Se un elemento non esiste nel secondo, ho bisogno di riempirlo con quello equivalente del primo.

Questo codice fa il lavoro, ma si sente inefficiente per me e mi obbliga a gettare le IEnumerables per ILists o per utilizzare un temporaneo lista persona implementa IEquatable

IEnumerable<Person> fallBack = Repository.GetPersons(); 
IList<Person> translated = Repository.GetPersons(language).ToList(); 

foreach (Person person in fallBack) 
{ 
    if (!translated.Any(p=>p.equals(person))) 
     translated.add(person); 
} 

Qualche suggerimento?

risposta

30

Prova questa.

public static IEnumerable<Person> SmartCombine(IEnumerable<Person> fallback, IEnumerable<Person> translated) { 
    return translated.Concat(fallback.Where(p => !translated.Any(x => x.id.equals(p.id))); 
} 
+4

Funziona alla perfezione ma c'è un trucco che devi conoscere: http://programmaticallyspeaking.com/how-enumerableconcat-brought-down-a-production-server.html – Oliver

49
translated.Union(fallback) 

o (se persona non implementa IEquatable<Person> per ID)

translated.Union(fallback, PersonComparer.Instance) 

dove PersonComparer è:

public class PersonComparer : IEqualityComparer<Person> 
{ 
    public static readonly PersonComparer Instance = new PersonComparer(); 

    // We don't need any more instances 
    private PersonComparer() {} 

    public int GetHashCode(Person p) 
    { 
     return p.id; 
    } 

    public bool Equals(Person p1, Person p2) 
    { 
     if (Object.ReferenceEquals(p1, p2)) 
     { 
      return true; 
     } 
     if (Object.ReferenceEquals(p1, null) || 
      Object.ReferenceEquals(p2, null)) 
     { 
      return false; 
     } 
     return p1.id == p2.id; 
    } 
} 
+1

Brillante - Come si dice, impari qualcosa di nuovo ogni giorno! –

+0

Beh, non è ancora tutto pronto ... –

+0

Questo funzionerà solo se la classe Person implementa correttamente l'uguaglianza. A giudicare dal PO sto cercando di indovinare. – JaredPar

0

utilizzare Concat. Union non funziona nel caso List<dynamic> tipo