Working through the examples:
array = [['a', 'b'], ['e', 'f', 'g']]
array.first.product(*array[1..-1]).map(&:flatten)
=> [["a", "e"], ["a", "f"], ["a", "g"], ["b", "e"], ["b", "f"], ["b", "g"]]
array = [['a', 'b'], ['c', 'd'], ['e', 'f', 'g']]
array.first.product(*array[1..-1]).map(&:flatten)
=> [["a", "c", "e"], ["a", "c", "f"], ["a", "c", "g"], ["a", "d", "e"], ["a", "d", "f"], ["a", "d", "g"], ["b", "c", "e"], ["b", "c", "f"], ["b", "c", "g"], ["b", "d", "e"], ["b", "d", "f"], ["b", "d", "g"]]
array = [['a', 'b'], ['c', 'd'], ['e', 'f', 'g'], ['h']]
array.first.product(*array[1..-1]).map(&:flatten)
=> [["a", "c", "e", "h"], ["a", "c", "f", "h"], ["a", "c", "g", "h"], ["a", "d", "e", "h"], ["a", "d", "f", "h"], ["a", "d", "g", "h"], ["b", "c", "e", "h"], ["b", "c", "f", "h"], ["b", "c", "g", "h"], ["b", "d", "e", "h"], ["b", "d", "f", "h"], ["b", "d", "g", "h"]]
Now, to 'splode that, product
is the method you want. Here are the pertinent excerpts from the documentation:
Returns an array of all combinations of elements from all arrays.
[1,2].product([3,4],[5,6]) #=> [[1,3,5],[1,3,6],[1,4,5],[1,4,6],
# [2,3,5],[2,3,6],[2,4,5],[2,4,6]]
The *
operator before *array[1..-1]
is also known as "splat", as in stomping on the array and squishing its contents out. It's the opposite of when we use *
with a parameter in a parameter list to a method, which probably should be called "vacuum" or "hoover" or "suck", but that last one is reserved for descriptions of my code. Its effect is hard to see in IRB because you can't use *array
, it has to be used where multiple arrays are allowed, as in product(other_ary, ...)
. array[1..-1]
would normally return an array of arrays, so *array[1..-1]
results in "arrays" instead of the original "arrays of arrays". I'm sure that's confusing but you'll get it.
So, if you need a method to do that:
def foo(array)
array.first.product(*array[1..-1]).map(&:flatten)
end
And poking at it:
foo(array)
=> [["a", "c", "e", "h"], ["a", "c", "f", "h"], ["a", "c", "g", "h"], ["a", "d", "e", "h"], ["a", "d", "f", "h"], ["a", "d", "g", "h"], ["b", "c", "e", "h"], ["b", "c", "f", "h"], ["b", "c", "g", "h"], ["b", "d", "e", "h"], ["b", "d", "f", "h"], ["b", "d", "g", "h"]]