Zyren
Zyren

Reputation: 663

Ruby - how to find a combination of results from picking 1 value from each array of a list of arrays

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

Answers (2)

tokland
tokland

Reputation: 67860

Array#product:

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

Faiz
Faiz

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

Related Questions