Digamos que tengo un número arbitrario de colecciones, cada una con objetos del mismo tipo (por ejemplo, List<int> fooy List<int> bar). Si estas colecciones estuvieran en una colección (por ejemplo, de tipo List<List<int>>, podría usar SelectManypara combinarlas todas en una colección.
Sin embargo, si estas colecciones no están ya en la misma colección, tengo la impresión de que tendría que escribir un método como este:
public static IEnumerable<T> Combine<T>(params ICollection<T>[] toCombine)
{
   return toCombine.SelectMany(x => x);
}Que luego llamaría así:
var combined = Combine(foo, bar);¿Existe una forma limpia y elegante de combinar (cualquier número de) colecciones sin tener que escribir un método de utilidad como el Combineanterior? Parece bastante simple que debería haber una forma de hacerlo en LINQ, pero tal vez no.
                    
                        c#
                                linq
                                generics
                                collections
                                
                    
                    
                        Rosquilla
fuente
                
                fuente

Respuestas:
Creo que podrías estar buscando LINQ's
.Concat().Alternativamente,
.Union()eliminará elementos duplicados.fuente
.Union()dato. Tenga en cuenta que deberá implementar IComparer en su tipo personalizado en caso de que lo sea.A mi
Concatcomo método de extensión, no es muy elegante en mi código cuando tengo varias secuencias grandes para concatizar. Esto es simplemente un problema de formato / sangría de codificación y algo muy personal.Seguro que se ve bien así:
No es tan legible cuando se lee como:
O cuando parece:
o cualquiera que sea su formato preferido. Las cosas empeoran con concats más complejos. La razón de mi tipo de disonancia cognitiva con el estilo anterior es que la primera secuencia se encuentra fuera del
Concatmétodo, mientras que las secuencias posteriores se encuentran dentro. Prefiero llamar alConcatmétodo estático directamente y no al estilo de extensión:Para más cantidad de concats de secuencias, llevo el mismo método estático que en OP:
Entonces puedo escribir:
Se ve mejor. El nombre de clase adicional, por lo demás redundante, que tengo que escribir no es un problema para mí, considerando que mis secuencias se ven más limpias con la
Concatllamada. Es un problema menor en C # 6 . Puedes simplemente escribir:Ojalá tuviéramos operadores de concatenación de listas en C #, algo como:
Mucho más limpio de esa manera.
fuente
Where,OrderBy) primero para mayor claridad, especialmente si son algo más complejas que este ejemplo.Para el caso en el que hacer tener una colección de colecciones, es decir una
List<List<T>>,Enumerable.Aggregatees una forma más elegante para combinar todas las listas en una sola:fuente
listsaquí primero? Ese es el primer problema que tiene OP. Si tuviera unacollection<collection>para empezar, entoncesSelectManyes mucho más simple.Use
Enumerable.Concatasí:fuente
Utilizar
Enumerable.Concact:fuente
Siempre puede usar Aggregate combinado con Concat ...
fuente
SelectManyes simplemente más simple.La única forma que veo es usar
Concat()Pero debes decidir qué es mejor:
o
Un punto por el
Concat()que será una mejor opción es que será más obvio para otro desarrollador. Más legible y simple.fuente
Puede utilizar Union de la siguiente manera:
Sin embargo, esto eliminará elementos idénticos, por lo que si los tiene, es posible que desee usarlos en su
Concatlugar.fuente
Enumerable.Uniones una unión de conjuntos que no produce el resultado deseado (solo produce duplicados una vez).inten mi ejemplo podría haber desconcertado un poco a la gente; peroUnionno funcionará para mí en este caso.Un par de técnicas que utilizan los inicializadores de colección:
asumiendo estas listas:
SelectManycon un inicializador de matriz (no es realmente tan elegante para mí, pero no depende de ninguna función auxiliar):Defina una extensión de lista para Agregar que permita
IEnumerable<T>en elList<T>inicializador :Luego puede crear una nueva lista que contenga los elementos de los demás como este (también permite que se mezclen elementos individuales).
fuente
Dado que está comenzando con un montón de colecciones separadas, creo que su solución es bastante elegante. Vas a tener que hacer algo para unirlos.
Sintácticamente, sería más conveniente crear un método de extensión a partir de su método Combine, lo que lo haría disponible en cualquier lugar al que vaya.
fuente
Todo lo que necesita es esto, para cualquier
IEnumerable<IEnumerable<T>> lists:Esto combinará todos los elementos en
listsunoIEnumerable<T>(con duplicados). Úselo enUnionlugar deConcatpara eliminar duplicados, como se indica en las otras respuestas.fuente