Disons que j'ai un nombre arbitraire de collections, chacune contenant des objets du même type (par exemple, List<int> foo
et 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 combiner toutes 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);
}
Ce que j'appellerais alors comme ceci:
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 comme Combine
ci-dessus? Cela semble assez simple qu'il devrait y avoir un moyen de le faire dans LINQ, mais peut-être pas.
la source
Réponses:
Je pense que vous recherchez peut-être LINQ
.Concat()
?Sinon,
.Union()
supprimera les éléments en double.la source
.Union()
pointe. Gardez à l'esprit que vous devrez implémenter IComparer sur votre type personnalisé au cas où il le serait.Pour moi
Concat
, une méthode d'extension n'est pas très élégante dans mon code lorsque j'ai plusieurs grandes séquences à concaténer. C'est simplement un problème d'indentation / formatage de code et quelque chose de très personnel.Bien sûr, cela ressemble à ceci:
Pas si lisible quand il se lit comme:
Ou quand ça ressemble à:
ou quel que soit votre formatage préféré. Les choses empirent avec des concats plus complexes. La raison de ma sorte de dissonance cognitive avec le style ci-dessus est que la première séquence se trouve en dehors de la
Concat
méthode alors que les séquences suivantes se trouvent à l'intérieur. Je préfère plutôt appeler laConcat
méthode statique directement et non le style d'extension:Pour plus de nombre de concats de séquences, je porte la même méthode statique que dans OP:
Donc je peux écrire:
Regarde mieux. Le nom de classe supplémentaire, sinon redondant, que je dois écrire n'est pas un problème pour moi étant donné que mes séquences semblent plus propres avec l'
Concat
appel. C'est moins un problème en C # 6 . Vous pouvez simplement écrire:J'aurais aimé avoir des opérateurs de concaténation de liste en C #, quelque chose comme:
Beaucoup plus propre de cette façon.
la source
Where
,OrderBy
) d' abord pour plus de clarté, surtout si elles sont quelque chose de plus complexe que cet exemple.Pour le cas lorsque vous faire une collection de collections, soit une
List<List<T>>
,Enumerable.Aggregate
est une façon plus élégante de combiner toutes les listes en une seule:la source
lists
ici en premier? C'est le premier problème d'OP. S'il avait uncollection<collection>
pour commencer,SelectMany
c'est bien plus simple.Utilisez
Enumerable.Concat
comme ça:la source
Utilisez
Enumerable.Concact
:la source
Vous pouvez toujours utiliser Aggregate combiné avec Concat ...
la source
SelectMany
est simplement plus simple.La seule façon que je vois est d'utiliser
Concat()
Mais vous devez décider de ce qui est mieux:
ou
Un des raisons
Concat()
pour lesquelles ce sera un meilleur choix est que ce sera plus évident pour un autre développeur. Plus lisible et simple.la source
Vous pouvez utiliser Union comme suit:
Cela supprimera les éléments identiques, donc si vous en avez, vous voudrez peut-être les utiliser à la
Concat
place.la source
Enumerable.Union
est une union d'ensemble qui ne produit pas le résultat souhaité (elle ne produit des doublons qu'une seule fois).int
dans mon exemple peut avoir dérangé un peu les gens; maisUnion
ne fonctionnera pas pour moi dans ce cas.Quelques techniques utilisant des initialiseurs de collection -
en supposant ces listes:
SelectMany
avec un initialiseur de tableau (pas vraiment élégant pour moi, mais ne repose sur aucune fonction d'assistance):Définissez une extension de liste pour Add qui permet
IEnumerable<T>
dans l'List<T>
initialiseur :Ensuite, vous pouvez créer une nouvelle liste contenant les éléments des autres comme celle-ci (cela permet également de mélanger des éléments uniques).
la source
Étant donné que vous commencez avec un tas de collections séparées, je pense que votre solution est plutôt élégante. Vous allez devoir faire quelque chose pour les assembler.
Il serait plus pratique de créer une méthode d'extension à partir de votre méthode Combine, ce qui la rendrait disponible partout où vous allez.
la source
Tout ce dont vous avez besoin est ceci, pour tout
IEnumerable<IEnumerable<T>> lists
:Cela combinera tous les éléments
lists
en un seulIEnumerable<T>
(avec des doublons). UtilisezUnion
au lieu deConcat
pour supprimer les doublons, comme indiqué dans les autres réponses.la source