J’ai trouvé que le message d’Eric Lippert ici correspond à un problème particulier que j’ai.
Le problème est que je ne peux pas comprendre comment je devrais l’utiliser avec un nombre de collections supérieur à 2.
Ayant
var collections = new List<List>(); foreach(var item in somequery) { collections.Add( new List { new MyType { Id = 1} .. n } ); }
Comment appliquer la requête linq de produit cartésien sur les collections variabile?
La méthode d’extension est celle-ci:
static IEnumerable<IEnumerable> CartesianProduct(this IEnumerable<IEnumerable> sequences) { IEnumerable<IEnumerable> emptyProduct = new[] { Enumerable.Empty()}; return sequences.Aggregate( emptyProduct, (accumulator, sequence) => from accseq in accumulator from item in sequence select accseq.Concat(new[] {item}) ); }
Voici l’exemple d’Eric pour 2 collections:
var arr1 = new[] {"a", "b", "c"}; var arr2 = new[] { 3, 2, 4 }; var result = from cpLine in CartesianProduct( from count in arr2 select Enumerable.Range(1, count)) select cpLine.Zip(arr1, (x1, x2) => x2 + x1);
L’exemple de code est déjà capable de créer “n” produits cartésiens (il en fait 3 dans l’exemple). Votre problème est que vous avez une List
lorsque vous avez besoin d’un >
IEnumerable
IEnumerable> result = collections .Select(list => list.AsEnumerable()) .CartesianProduct();
Puisque List
est IEnumerable
, votre problème à l’aide de la solution d’Eric est résolu comme suit:
var collections = new List>(); var product = collections.CartesianProduct(); foreach(var collection in product) { // a single collection of MyType items foreach(var item in collection) { // each item of type MyType within a collection Console.Write(item); } }
Bien entendu, vous pouvez regrouper les éléments de chaque collection de manière plus concise, par exemple sous la forme d’une ssortingng
unique:
var product = collections .CartesianProduct() .Select(xs => xs.Aggregate(new SsortingngBuilder(), (sb, x) => sb.Append(x.ToSsortingng()), sb => sb.ToSsortingng())); foreach(var collectionAsSsortingng in product) { Console.WriteLine(collectionAsSsortingng); }