Manière élégante de combiner plusieurs collections d'éléments?
Dire que j'ai un nombre arbitraire de collections, chacune contenant des objets de même type (par exemple, List<int> foo
et List<int> bar
). Si ces collections ont été eux-mêmes dans une collection (par exemple, de type List<List<int>>
, je pourrais utiliser SelectMany
les combiner en une seule collection.
Toutefois, si ces collections ne sont pas déjà dans la même collection, c'est mon impression que j'aurais à écrire une méthode comme ceci:
public static IEnumerable<T> Combine<T>(params ICollection<T>[] toCombine)
{
return toCombine.SelectMany(x => x);
}
Que j'ai ensuite appeler comme ceci:
var combined = Combine(foo, bar);
Est-il propre, élégante façon de combiner (n'importe quel nombre de collections sans avoir à écrire une méthode utilitaire comme Combine
ci-dessus? Il semble assez simple qu'il devrait y avoir un moyen de le faire dans LINQ, mais peut-être pas.
Vous devez vous connecter pour publier un commentaire.
Je pense que vous pourriez être à la recherche pour LINQ
.Concat()
?Sinon,
.Union()
va supprimer les éléments en double..Union()
pointe. Gardez à l'esprit que vous devez pour mettre en œuvre IComparer sur mesure pour votre type dans le cas où il est.Pour moi
Concat
comme une extension de la méthode n'est pas très élégant dans mon code quand j'ai plusieurs grandes séquences de concat. Ce n'est qu'un codde indentation/mise en forme du problème et quelque chose de très personnel.Sûr que ça a l'air bien comme ceci:
Pas si lisible lorsqu'il se lit comme:
Ou quand il ressemble:
ou quel que soit votre choix de mise en forme est. Les choses s'aggraver avec plus de complexe concats. La raison de mon sorte de dissonance cognitive avec le style précédent, c'est que la première séquence se trouvent en dehors de la
Concat
méthode alors que les séquences se trouvent à l'intérieur. Je préfère l'appeler la statiqueConcat
méthode directement et non à l'extension de style:Pour plus de nombre de concats de séquences que j'portent la même méthode statique comme dans l'OP:
Afin que je puisse écrire:
Regarde mieux. L'extra, redondants, nom de la classe que j'ai écrit n'est pas un problème pour moi compte tenu de mon séquences look plus propre avec le
Concat
appel. C'est moins un problème dans C# 6. Il vous suffit d'écrire:Souhaité nous avait liste des opérateurs de concaténation en C#, quelque chose comme:
Beaucoup plus propre comme ça.
Where
,OrderBy
) d'abord pour des raisons de clarté, surtout si elles sont quelque chose de plus complexe que cet exemple.Pour le cas où vous ne ont une collection de collections, c'est à dire un
List<List<T>>
,Enumerable.Aggregate
est une façon plus élégante de combiner toutes les listes en une seule:lists
ici d'abord? C'est le premier problème de l'OP a. Si il avait uncollection<collection>
pour commencer puisSelectMany
est juste plus simple.Utilisation
Énumérable.Concat
comme suit:Utilisation
Énumérable.Adresser
:Vous pouvez toujours utiliser l'Agrégat combiné avec Concat...
Le seul moyen que je vois est d'utiliser
Concat()
Mais vous devez décider ce qui est mieux:
ou
Un point pourquoi
Concat()
sera un meilleur choix est qu'il sera plus évident pour un autre développeur. Plus lisible et plus simple.Vous pouvez utiliser de l'Union comme suit:
Cela permettra d'éliminer des éléments identiques, bien, donc si vous avez ceux-ci, vous pourriez vouloir utiliser
Concat
, à la place.Enumerable.Union
est un ensemble de l'union qui ne produit pas le résultat escompté (il ne les rendements des doublons une fois).int
dans mon exemple, pourrait avoir jeté des gens un peu; maisUnion
de ne pas travailler pour moi dans ce cas.Étant donné que vous êtes débutant avec un tas de collections distinctes, je pense que votre solution est plutôt élégant. Vous allez avoir à faire quelque chose à les réunir.
Il serait plus commode du point de vue syntaxique de faire une méthode d'extension de votre méthode de combinaison, qui rendrait disponible partout où vous allez.
Tous vous avez besoin est cela, pour tout
IEnumerable<IEnumerable<T>> lists
:Ce sera de combiner tous les éléments dans
lists
dans unIEnumerable<T>
(avec doublons). UtilisationUnion
au lieu deConcat
de supprimer les doublons, comme indiqué dans les autres réponses.