124 votes

Une façon élégante de combiner plusieurs collections d'éléments ?

Supposons que je dispose d'un nombre arbitraire de collections, chacune contenant des objets du même type (par exemple, List<int> foo y List<int> bar ). Si ces collections étaient elles-mêmes dans une collection (par exemple, de type List<List<int>> Je pourrais utiliser SelectMany pour les réunir en une seule collection.

Cependant, si ces collections ne sont pas déjà dans la même collection, j'ai l'impression que je devrais écrire une méthode comme celle-ci :

public static IEnumerable<T> Combine<T>(params ICollection<T>[] toCombine)
{
   return toCombine.SelectMany(x => x);
}

Que j'appellerais alors ainsi :

var combined = Combine(foo, bar);

Existe-t-il un moyen propre et élégant de combiner (un nombre quelconque de) collections sans avoir à écrire une méthode utilitaire telle que Combine ci-dessus ? Cela semble suffisamment simple pour qu'il y ait un moyen de le faire dans LINQ, mais ce n'est peut-être pas le cas.

12voto

Ahmad Mageed Points 44495

Utilice Enumerable.Concat :

var query = foo.Concat(bar);

6voto

Restuta Points 4476

La seule solution que je vois est d'utiliser Concat()

 var foo = new List<int> { 1, 2, 3 };
 var bar = new List<int> { 4, 5, 6 };
 var tor = new List<int> { 7, 8, 9 };

 var result = foo.Concat(bar).Concat(tor);

Mais c'est à vous de décider ce qui est le mieux :

var result = Combine(foo, bar, tor);

ou

var result = foo.Concat(bar).Concat(tor);

Un point pourquoi Concat() sera un meilleur choix est qu'elle sera plus évidente pour un autre développeur. Plus lisible et plus simple.

3voto

Michael Goldshteyn Points 24679

Vous pouvez utiliser l'Union comme suit :

var combined=foo.Union(bar).Union(baz)...

Cependant, cela supprimera les éléments identiques, donc si vous en avez, vous voudrez peut-être utiliser Concat au lieu de cela.

2voto

Nir Maoz Points 33

Tout ce dont vous avez besoin, c'est de ceci, pour n'importe quel IEnumerable<IEnumerable<T>> lists :

var combined = lists.Aggregate((l1, l2) => l1.Concat(l2));

Cette opération permet de combiner tous les éléments dans lists en un seul IEnumerable<T> (avec doublons). Utiliser Union au lieu de Concat pour supprimer les doublons, comme indiqué dans les autres réponses.

2voto

Dave Andersen Points 1822

Quelques techniques utilisant les initialisateurs de collection --

en assumant ces listes :

var list1 = new List<int> { 1, 2, 3 };
var list2 = new List<int> { 4, 5, 6 };

SelectMany avec un initialisateur de tableau (ce n'est pas très élégant pour moi, mais cela ne dépend d'aucune fonction d'aide) :

var combined = new []{ list1, list2 }.SelectMany(x => x);

Définir une extension de liste pour Add qui permet IEnumerable<T> dans le List<T> initialisateur :

public static class CollectionExtensions
{
    public static void Add<T>(this ICollection<T> collection, IEnumerable<T> items)
    {
        foreach (var item in items) collection.Add(item);
    }
}

Vous pouvez ensuite créer une nouvelle liste contenant les éléments des autres listes de cette manière (cela permet également de mélanger des éléments uniques).

var combined = new List<int> { list1, list2, 7, 8 };

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X