Say I have a data structure of IEnumerable<IEnumerable<object>>
like this:
{
{ A, B }
{ 1, 2, 3 }
{ Z }
}
Where the outer array can contain any number of inner arrays. And the inner arrays can each independently contain any number of elements. And assume, for the sake of simplicity, that no array will be empty.
And I want to transform it to a IEnumerable<IEnumerable<object>>
like this:
{ { A, 1, Z }, { A, 2, Z }, { A, 3, Z }, { B, 1, Z }, { B, 2, Z }, { B, 3, Z } }
Which contains every combination of the values from the original structure. So each element in each inner array maps by index to an element/array in the original outer array.
What is the simplest way to do that in C#?
To create combination of multiple vectors, we can use expand. grid function. For example, if we have six vectors say x, y, z, a, b, and c then the combination of vectors can be created by using the command expand.
You could use CartesianProduct
method by Eric Lippert for this (taken from here):
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}));
}
private static IEnumerable<IEnumerable<object>> GetAllCombinations(IEnumerable<IEnumerable<object>> a)
{
if (!a.Skip(1).Any())
{
return a.First().Select(x => new[] { x });
}
var tail = GetAllCombinations(a.Skip(1)).ToArray();
return a.First().SelectMany(f => tail.Select(x => new[] { f }.Concat(x)));
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With