2009-02-26 8 views
40

Ich habe zwei IEnumerable<T> s.Verschmelzung von zwei IEnumerable <T> s

Man wird mit den Fallback Ellements gefüllt. Dieser enthält immer die meisten Elemente. Der andere wird abhängig von einigen Parametern gefüllt und enthält möglicherweise weniger Elemente. Wenn ein Element in der zweiten nicht existiert, muss ich es mit dem Äquivalent der ersten füllen.

Dieser Code macht den Job, aber fühlt sich für mich ineffizient und erfordert mir die IEnumerables zu ILists zu werfen oder eine temporäre Liste Person implementiert 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); 
} 

Irgendwelche Vorschläge zu benutzen?

Antwort

30

bereits.

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

Das funktioniert gut, aber es gibt ein Problem, das Sie beachten müssen: http://programmatigatically speaking.com/how-enumerableconcat-broughtdown-a-production-server.html – Oliver

49
translated.Union(fallback) 

oder

(wenn Person IEquatable<Person> von ID nicht implementiert)
translated.Union(fallback, PersonComparer.Instance) 

wo PersonComparer ist:

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

Brilliant - Wie sie sagen, lernen Sie jeden Tag etwas Neues! –

+0

Nun, es ist noch nicht ganz fertig ... –

+0

Das funktioniert aber nur, wenn die Person-Klasse Equality korrekt implementiert. Nach dem OP zu urteilen, schätze ich, dass sie es nicht tun. – JaredPar

0

Concat verwenden. Union funktioniert nicht im Fall List<dynamic> Typ

Verwandte Themen