Combinar dos (o más) listas en una, en C#.NET


¿Es posible convertir dos o más listas en una sola lista, en. NET usando C#?

Por ejemplo,

public static List<Product> GetAllProducts(int categoryId){ .... }
.
.
.
var productCollection1 = GetAllProducts(CategoryId1);
var productCollection2 = GetAllProducts(CategoryId2);
var productCollection3 = GetAllProducts(CategoryId3);
 172
Author: zekia, 2010-12-20

12 answers

Puede utilizar el LINQ Concat y ToList métodos:

var allProducts = productCollection1.Concat(productCollection2)
                                    .Concat(productCollection3)
                                    .ToList();

Tenga en cuenta que hay formas más eficientes de hacer esto: lo anterior básicamente recorrerá todas las entradas, creando un búfer de tamaño dinámico. Como puede predecir el tamaño para comenzar, no necesita este tamaño dinámico... así que podría usar:

var allProducts = new List<Product>(productCollection1.Count +
                                    productCollection2.Count +
                                    productCollection3.Count);
allProducts.AddRange(productCollection1);
allProducts.AddRange(productCollection2);
allProducts.AddRange(productCollection3);

(AddRange es especial-cased para ICollection<T> para la eficiencia.)

No adoptaría este enfoque a menos que realmente tenga que hacerlo aunque.

 342
Author: Jon Skeet,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-12-20 08:45:35

Asumiendo que desea una lista que contenga todosde los productos para los identificadores de categoría especificados, puede tratar su consulta como una proyección seguida de una operación aplanamiento. Hay un operador LINQ que hace eso: SelectMany.

// implicitly List<Product>
var products = new[] { CategoryId1, CategoryId2, CategoryId3 }
                     .SelectMany(id => GetAllProducts(id))
                     .ToList();

En C # 4, puede acortar el SelectMany a: .SelectMany(GetAllProducts)

Si ya tiene listas que representan los productos para cada Id, entonces lo que necesita es una concatenación , como otros señalan.

 33
Author: Ani,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-12-20 08:57:13

Puedes combinarlos usando LINQ:

  list = list1.Concat(list2).Concat(list3).ToList();

El enfoque más tradicional de usar List.AddRange() podría ser más eficiente.

 21
Author: Botz3000,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-12-20 08:47:39

Puedes usar el método de extensión Concat :

var result = productCollection1
    .Concat(productCollection2)
    .Concat(productCollection3)
    .ToList();
 7
Author: Darin Dimitrov,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-12-20 08:45:24
list4 = list1.Concat(list2).Concat(list3).ToList();
 7
Author: decyclone,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-12-20 08:45:47

Echa un vistazo a la lista .AddRange para fusionar listas

 7
Author: StuartLC,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-12-20 08:46:15

Ya lo he comentado pero sigo pensando que es una opción válida, solo prueba si en tu entorno es mejor una solución u otra. En mi caso particular, usar source.ForEach(p => dest.Add(p)) funciona mejor que el clásico AddRange pero no he investigado por qué en el nivel bajo.

Puedes ver un código de ejemplo aquí: https://gist.github.com/mcliment/4690433

Así que la opción sería:

var allProducts = new List<Product>(productCollection1.Count +
                                    productCollection2.Count +
                                    productCollection3.Count);

productCollection1.ForEach(p => allProducts.Add(p));
productCollection2.ForEach(p => allProducts.Add(p));
productCollection3.ForEach(p => allProducts.Add(p));

Pruébelo para ver si funciona para usted.

Descargo de responsabilidad : No soy abogando por esta solución, encuentro Concat la más clara. Acabo de decir - en mi discusión con Jon - que en mi máquina este caso funciona mejor que AddRange, pero él dice, con mucho más conocimiento que yo, que esto no tiene sentido. Ahí está la esencia si quieres comparar.

 2
Author: Marc Climent,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-07-15 10:59:01

Necesita usar la operación Concat

 1
Author: Artem,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-12-20 08:45:12

Sé que esta es una vieja pregunta que pensé que podría agregar mis 2 centavos.

Si tienes un List<Something>[] puedes unirte a ellos usando Aggregate

public List<TType> Concat<TType>(params List<TType>[] lists)
{
    var result = lists.Aggregate(new List<TType>(), (x, y) => x.Concat(y).ToList());

    return result;
}

Espero que esto ayude.

 1
Author: sQuir3l,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-04-05 07:21:51

En el caso especial: "Todos los elementos de List1 van a una nueva List2": (por ejemplo, una lista de cadenas)

List<string> list2 = new List<string>(list1);

En este caso, list2 se genera con todos los elementos de list1.

 0
Author: Arthur Zennig,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-31 12:33:52
// I would make it a little bit more simple

 var products = new List<List<product>> {item1, item2, item3 }.SelectMany(id => id).ToList();

De esta manera es una lista multidimensional y la.SelectMany() lo aplanará en un productumerable de producto y luego utilizo el .Método ToList () después.

 0
Author: Gringo Jaimes,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-07-02 20:06:25

Cuando tengas pocas listas pero no sepas cuántas exactamente, usa esto:

listsOfProducts contiene pocas listas llenas de objetos.

List<Product> productListMerged = new List<Product>();

listsOfProducts.ForEach(q => q.ForEach(e => productListMerged.Add(e)));
 0
Author: john.kernel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-02-28 11:28:00