Okomikeruko Okomikeruko -3 years ago 108
Ruby Question

Adding parameters to Array Product function in Ruby

So I've been scratching my head trying to find a solution to this.

I need a method that will take any number of arrays that I need to collect the product of.

1 array:

return [A, B, C] # => [A, B, C]

2 arrays:

return [A, B, C].product([1, 2, 3]) # => [[A, 1], [A, 2], [A, 3], [B, 1] ... [C, 3]]

3 arrays:

return [A, B, C].product([1, 2, 3,],[x, y, z]) # => [[A, 1, x], [A, 1, y], ... [C, 3, z]]

So my current solution is this case switch, which is functional but inconvenient.

case options.count
when 1
when 2
when 3
when 4

What I'm looking for is a method that procedurally or recursively returns the product of an unknown number of arrays. The output needs to be like the above arrays.

I've tried:

array = options[0].values
options.each_with_index do |option, i|
array = array.product(option.values) if i > 0
return array

But it returns:

[[[A, 1], x], [[A, 1], y], [[A, 1], z], [[A, 2], x], ... [[C, 3], z]]

Which groups the values incorrectly.

Answer Source

Hope this helps

a =  [["a", "b", "c"], ["d", "e", "f"], ["g", "h", "i"]]
#=> [["a", "d", "g"], ["a", "d", "h"], ["a", "d", "i"], ["a", "e", "g"], ["a", "e", "h"], ["a", "e", "i"], ["a", "f", "g"], ["a", "f", "h"], ["a", "f", "i"], ["b", "d", "g"], ["b", "d", "h"], ["b", "d", "i"], ["b", "e", "g"], ["b", "e", "h"], ["b", "e", "i"], ["b", "f", "g"], ["b", "f", "h"], ["b", "f", "i"], ["c", "d", "g"], ["c", "d", "h"], ["c", "d", "i"], ["c", "e", "g"], ["c", "e", "h"], ["c", "e", "i"], ["c", "f", "g"], ["c", "f", "h"], ["c", "f", "i"]]
# or 
a.slice!(0).product(*a) #Note: this mutates array.
# or
a[0].product(*a.drop(1)) # suggested by Cary Swoveland
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download