### Recursive algorithm to generate all combinations of elements in successive enumerables

If you need to flatten ordered enumerables, that is taking one element of each enumerable, in order, to flatten a combination, here is a quick solution in C# and VB.NET, accompanied with an example:

Code in VB.NET:

```Private Shared Sub GetCombinationsRec(Of T)(sources As IList(Of IEnumerable(Of T)), chain As T(), index As Integer, combinations As ICollection(Of T()))
For Each element As var In sources(index)
chain(index) = element
If index Is sources.Count - 1 Then
Dim finalChain = New T(chain.Length - 1) {}
chain.CopyTo(finalChain, 0)
Else
GetCombinationsRec(sources := sources, chain := chain, index := index + 1, combinations := combinations)
End If
Next
End Sub

Public Shared Function GetCombinations(Of T)(ParamArray enumerables As IEnumerable(Of T)()) As List(Of T())
Dim combinations = New List(Of T())(enumerables.Length)
If enumerables.Length > 0 Then
Dim chain = New T(enumerables.Length - 1) {}
GetCombinationsRec(sources := enumerables, chain := chain, index := 0, combinations := combinations)
End If
Return combinations
End Function```

Code in C#.NET:

```private static void GetCombinationsRec<T>(IList<IEnumerable<T>> sources, T[] chain, int index, ICollection<T[]> combinations) {
foreach (var element in sources[index]) {
chain[index] = element;
if (index == sources.Count - 1) {
var finalChain = new T[chain.Length];
chain.CopyTo(finalChain, 0);
}
else {
GetCombinationsRec(sources: sources, chain: chain, index: index + 1, combinations: combinations);
}
}
}

public static List<T[]> GetCombinations<T>(params IEnumerable<T>[] enumerables) {
var combinations = new List<T[]>(enumerables.Length);
if (enumerables.Length > 0) {
var chain = new T[enumerables.Length];
GetCombinationsRec(sources: enumerables, chain: chain, index: 0, combinations: combinations);
}
return combinations;
}```

Usage is simple:

```Dim list1 = New String() {"hello", "bonjour", "hallo", "hola"}
Dim list2 = New String() {"Erwin", "Larry", "Bill", "Steve"}
Dim list3 = New String() {"!", ".."}
Dim result = Utils.GetCombinations(list1, list2, list3)
For Each r In result
Debug.Print(String.Join(" "c, r))
Next```

or in C#:

```var list1 = new[] { "Hello", "Bonjour", "Hallo", "Hola" };
var list2 = new[] { "Erwin", "Larry", "Bill", "Steve" };
var list3 = new[] { "!", "..." };
var result = Utils.GetCombinations(list1, list2, list3);
foreach (r in result) {
Debug.Print(string.Join(" ", r));
}```

As with any recursive function, memory usage can be exponential so make sure you know the number of target combinations is reasonable. Speed-wise, parallelizing this function is not worth it as we are just iterating over the elements.