Reputation: 663
Lets say i have the following arrays in ruby contained in an array and I don't know how many arrays there will be or the length of them. An example below:
[["cat", "dog"],[1, 3, 5, 7],["morning", "afternoon", "evening"]]
what i want to do is have all combinations of results from picking 1 value from each array and returning it as an array of these combinations. Therefore, in the following example, there should be 2*4*3, or 24 possible unique results.
the result would be like :
result = [["cat", 1, "morning"], ["cat", 1, "afternoon"], ["dog", 5, "evening"] ...]
How would i go about doing this in ruby for a list of N arrays? I tried messing around with products and maps and injects but I cant get it working.
Upvotes: 2
Views: 121
Reputation: 67860
xs[0].product(*xs.drop(1))
Note that you'd rather like to write Array.product(*xs)
, but Ruby has no such classmethod in the core (easy to write, sure, but probably it should be there).
Upvotes: 3
Reputation: 16255
EDIT Since you made it clear that you're dealing with not just three arrays a1
, a2
and a3
but an arrays of arrays, changing my solution to use product
.
Like this?
a1.map{|x1| a2.map{|x2| a3.map{|x3| [x1, x2, x3] }}}.flatten(2)
Or with flat_map
:
a1.flat_map{|x1| a2.flat_map{|x2| a3.map{|x3| [x1, x2, x3] }}}
Wow, or just:
a1.product(a2,a3)
If you have several arrays (not just the fixed number of 3 in you first example), then:
input = [["cat", "dog"],[1, 3, 5, 7],["morning", "afternoon", "evening"]]
h,*rest = input
result = h.product(*rest)
Upvotes: 4