Génération d’un exemple de produit cartésien n-aire

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