问题
I found that Eric Lippert's post here suits a particular problem I have.
The problem is I can't wrap my head around how I should be using it with a 2+ amount of collections.
Having
var collections = new List<List<MyType>>();
foreach(var item in somequery)
{
collections.Add(
new List<MyType> { new MyType { Id = 1} .. n }
);
}
How do I apply the cartesian product linq query on the collections variabile ?
The extension method is this one:
static IEnumerable<IEnumerable<T>> CartesianProduct<T>(this IEnumerable<IEnumerable<T>> sequences)
{
IEnumerable<IEnumerable<T>> emptyProduct = new[] { Enumerable.Empty<T>()};
return sequences.Aggregate(
emptyProduct,
(accumulator, sequence) =>
from accseq in accumulator
from item in sequence
select accseq.Concat(new[] {item})
);
}
Here is Eric's example for 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);
回答1:
The sample code is already able to do "n" cartesian products (it does 3 in the example). Your problem is that you have a List<List<MyType>>
when you need an IEnumerable<IEnumerable<MyType>>
IEnumerable<IEnumerable<MyType>> result = collections
.Select(list => list.AsEnumerable())
.CartesianProduct();
回答2:
Since List<T>
is IEnumerable<T>
, then your problem using Eric's solution is solved as follows:
var collections = new List<List<MyType>>();
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);
}
}
Of course you can aggregate the items from each collection in a more concise manner, for example as a single string
:
var product =
collections
.CartesianProduct()
.Select(xs => xs.Aggregate(new StringBuilder(), (sb, x) => sb.Append(x.ToString()), sb => sb.ToString()));
foreach(var collectionAsString in product)
{
Console.WriteLine(collectionAsString);
}
来源:https://stackoverflow.com/questions/13647662/generating-a-n-ary-cartesian-product-example