2009-02-26 17 views
40

Tengo dos IEnumerable<T> s.Fusionando dos IEnumerable <T> s

Uno se llena con los elementos de reserva. Este siempre contendrá la mayoría de los elementos. El otro se llenará dependiendo de algunos parámetros y posiblemente contendrá menos elementos. Si un elemento no existe en el segundo, necesito llenarlo con el equivalente del primero.

Este código hace el trabajo, pero se siente ineficaz a mí y me obliga a emitir los IEnumerables a ILists o para usar una lista temporal 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); 
} 

¿Alguna sugerencia?

Respuesta

30

probar esto.

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

Esto funciona bien, pero hay un problema que debe tener en cuenta: http://programmaticallyspeaking.com/how-enumerableconcat-brought-down-a-production-server.html – Oliver

49
translated.Union(fallback) 

o (si la persona no implementa IEquatable<Person> por ID)

translated.Union(fallback, PersonComparer.Instance) 

donde PersonComparer es:

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 - ¡Como dicen, aprendes algo nuevo todos los días! –

+0

Bueno, todavía no está listo ... –

+0

Eso solo funcionará si la clase Persona implementa correctamente la igualdad. A juzgar por el OP, supongo que no. – JaredPar

0

uso Concat. Union no funciona en el caso List<dynamic> tipo

Cuestiones relacionadas