I have an array of arrays, like so:
[['1','2'],['a','b'],['x','y']]
I need to combine those arrays into a string containing all possible combinations of all three sets, forward only. I have seen lots of examples of all possible combinations of the sets in any order, that is not what I want. For example, I do not want any of the elements in the first set to come after the second set, or any in the third set to come before the first, or second, and so on. So, for the above example, the output would be:
['1ax', '1ay', '1bx', '1by', '2ax', '2ay', '2bx', '2by']
The number of arrays, and length of each set is dynamic.
Does anybody know how to solve this in Ruby?
Know your Array#product
:
a = [['1','2'],['a','b'],['x','y']] a.first.product(*a[1..-1]).map(&:join)
Solved using a recursive, so-called "Dynamic Programming" approach:
In code:
def variations(a) first = a.first if a.length==1 then first else rest = variations(a[1..-1]) first.map{ |x| rest.map{ |y| "#{x}#{y}" } }.flatten end end p variations([['1','2'],['a','b'],['x','y']]) #=> ["1ax", "1ay", "1bx", "1by", "2ax", "2ay", "2bx", "2by"] puts variations([%w[a b],%w[M N],['-'],%w[x y z],%w[0 1 2]]).join(' ') #=> aM-x0 aM-x1 aM-x2 aM-y0 aM-y1 aM-y2 aM-z0 aM-z1 aM-z2 aN-x0 aN-x1 aN-x2 #=> aN-y0 aN-y1 aN-y2 aN-z0 aN-z1 aN-z2 bM-x0 bM-x1 bM-x2 bM-y0 bM-y1 bM-y2 #=> bM-z0 bM-z1 bM-z2 bN-x0 bN-x1 bN-x2 bN-y0 bN-y1 bN-y2 bN-z0 bN-z1 bN-z2
You could also reverse the logic, and with care you should be able to implement this non-recursively. But the recursive answer is rather straightforward. :)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With