web-dev-qa-db-fra.com

Fusionner deux listes (ou plus) en une seule, en C # .NET

Est-il possible de convertir deux ou plusieurs listes en une seule liste, en .NET en utilisant C #?

Par exemple, 

public static List<Product> GetAllProducts(int categoryId){ .... }
.
.
.
var productCollection1 = GetAllProducts(CategoryId1);
var productCollection2 = GetAllProducts(CategoryId2);
var productCollection3 = GetAllProducts(CategoryId3);
187
zekia

Vous pouvez utiliser les méthodes LINQ Concat et ToList :

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

Notez qu'il existe des moyens plus efficaces de le faire - la procédure ci-dessus parcourt toutes les entrées, créant ainsi un tampon de taille dynamique. Comme vous pouvez prédire la taille de départ, vous n'avez pas besoin de ce dimensionnement dynamique ... de sorte que vous pourriez utiliser:

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

(AddRange a une casse spéciale pour ICollection<T> pour plus d'efficacité.)

Je ne prendrais pas cette approche à moins d'y être vraiment obligé.

363
Jon Skeet

En supposant que vous souhaitiez une liste contenant tous les produits correspondant aux ID de catégorie spécifiés, vous pouvez traiter votre requête comme une projection suivie par une opération aplatissement . Un opérateur LINQ fait cela: SelectMany .

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

En C # 4, vous pouvez raccourcir le SelectMany en: .SelectMany(GetAllProducts)

Si vous avez déjà des listes représentant les produits pour chaque ID, vous avez besoin d'une concaténation , comme le soulignent les autres.

39
Ani

vous pouvez les combiner avec LINQ:

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

l'approche plus traditionnelle consistant à utiliser List.AddRange() pourrait toutefois être plus efficace.

21
Botz3000

Vous pouvez utiliser la méthode Concat extension:

var result = productCollection1
    .Concat(productCollection2)
    .Concat(productCollection3)
    .ToList();
7
Darin Dimitrov
list4 = list1.Concat(list2).Concat(list3).ToList();
7
decyclone

Regardez List.AddRange pour fusionner des listes

7
StuartLC

Je l'ai déjà commenté, mais je pense toujours que c'est une option valable. Il suffit de tester si, dans votre environnement, il vaut mieux une solution ou l'autre. Dans mon cas particulier, utiliser source.ForEach(p => dest.Add(p)) donne de meilleurs résultats que le AddRange classique, mais je n’ai pas cherché à savoir pourquoi au niveau bas.

Vous pouvez voir un exemple de code ici: https://Gist.github.com/mcliment/4690433

Donc, l'option serait:

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));

Testez-le pour voir si cela fonctionne pour vous.

Déni de responsabilité: Je ne préconise pas cette solution, je trouve Concat la plus claire. Je viens de dire - dans ma discussion avec Jon - que dans ma machine, cette affaire fonctionne mieux que AddRange, mais il dit, avec beaucoup plus de connaissances que moi, que cela n’a aucun sens. Il y a le Gist si vous voulez comparer.

2
Marc Climent

Je sais que c’est une vieille question et je pensais pouvoir ajouter mes 2 centimes.

Si vous avez un List<Something>[], vous pouvez les rejoindre en utilisant 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;
}

J'espère que cela t'aides.

1
sQuir3l
// I would make it a little bit more simple

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

De cette façon, il s’agit d’une liste multidimensionnelle et le .SelectMany () l’aplatira dans un IEnumerable de produit, puis j’utilise la méthode .ToList () après.

1
Gringo Jaimes

Dans le cas spécial: "Tous les éléments de List1 vont dans une nouvelle List2": (par exemple une liste de chaînes)

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

Dans ce cas, list2 est généré avec tous les éléments de list1.

0
Arthur Zennig

Pour fusionner ou combiner des listes en une seule liste.

  • Il y a une chose qui doit être vraie: le type des deux listes sera Égal.

  • Par exemple : si nous avons une liste de string afin que nous puissions ajouter une autre liste à la liste existante Qui possède une liste de type chaîne sinon nous ne pouvons pas.

Exemple :

class Program
{
   static void Main(string[] args)
   {
      List<string> CustomerList_One = new List<string> 
      {
         "James",
         "Scott",
         "Mark",
         "John",
         "Sara",
         "Mary",
         "William",
         "Broad",
         "Ben",
         "Rich",
         "Hack",
         "Bob"
      };

      List<string> CustomerList_Two = new List<string> 
      {
         "Perter",
         "Parker",
         "Bond",
         "been",
         "Bilbo",
         "Cooper"
      };

      // Adding all contents of CustomerList_Two to CustomerList_One.
      CustomerList_One.AddRange(CustomerList_Two);

      // Creating another Listlist and assigning all Contents of CustomerList_One.
      List<string> AllCustomers = new List<string>();

      foreach (var item in CustomerList_One)
      {
         AllCustomers.Add(item);
      }

      // Removing CustomerList_One & CustomerList_Two.
      CustomerList_One = null;

      CustomerList_Two = null;
      // CustomerList_One & CustomerList_Two -- (Garbage Collected)
      GC.Collect();

      Console.WriteLine("Total No. of Customers : " +  AllCustomers.Count());
      Console.WriteLine("-------------------------------------------------");
      foreach (var customer in AllCustomers)
      {
         Console.WriteLine("Customer : " + customer);
      }
      Console.WriteLine("-------------------------------------------------");

   }
}
0
Rehan Shah

Vous devez utiliser l'opération Concat

0
Artem

Quand vous avez peu de liste mais vous ne savez pas combien exactement, utilisez ceci:

listsOfProducts contient peu de listes remplies d'objets.

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

listsOfProducts.ForEach(q => q.ForEach(e => productListMerged.Add(e)));
0
john.kernel