As stated in the comments Eric Lippert has a blog post named Computing a Cartesian Product with LINQ that explains how to solve your problem. You need an extension method to compute the cartesian product:
public static IEnumerable<IEnumerable<T>> CartesianProduct<T>(this IEnumerable<IEnumerable<T>> sequences) {
IEnumerable<IEnumerable<T>> result = new [] { Enumerable.Empty<T>() };
foreach (var sequence in sequences) {
var localSequence = sequence;
result = result.SelectMany(
_ => localSequence,
(seq, item) => seq.Concat(new[] { item })
);
}
return result;
}
Then you need a sequence of sequences to perform the product over. In your case you have both strings and integers in your sequences so the common base type T
has to be Object
.
var sequences = new[] {
new Object[] { "black", "white", "red" },
new Object[] { 30, 32, 34, 36, 38 },
new Object[] { 28, 30, 32, 34 }
};
To compute the Cartesian product you simply invoke the extension method:
var result = sequences.CartesianProduct();
When you enumerate the result it is computed on the fly (lazily). If you prefer to create a list of lists you need to call ToList()
after Concat
and also before returning result
from the extension method.