coconup - 5 months ago 27
Ruby Question

# Ruby: multidimensional array to one-dimensional rows

In Ruby, how do I go from this:

``````[
1,
["green", "blue", "black"],
[ ["1", "2"], ["3"], ["4", "5"] ]
]
``````

to this?

``````[
[1, "green", "1"],
[1, "green", "2"],
[1, "blue", "3"],
[1, "black", "4"],
[1, "black", "5"],
]
``````

I tried .zip but with no luck. Any help is greatly appreciated, and of course I'm looking for a performant solution.

I needed a more generic and flexible solution as compared to the ones proposed (my bad, I should have been more clear about the requirements), so I came up with the following:

``````class Array
def transpose_rows
arys = self.select{|el| el.is_a?(Array)}
if arys.size == 0
[self]
else
result = []
(arys.map(&:size).max || 1).times.map{ |i|
self.map { |r|
r.is_a?(Array) ? r[i] : r
}.transpose_rows.map{|r| result << r}
}
result
end
end
end
``````

The initial spec is that every element in the array is either a value or another array of varying depth. Each subarray "explodes" the values of the subarrays of depth-1 into an arbitrary number of "sub-values". The result should be a set of rows listing all combinations deriving from the original array.

The other solutions proposed do work for the original array I posted, which was just an example, while this one works for more complex scenarios such as the following:

``````[
2,
[3,4,5],
6,
[7,8,9],
[ [11,22], [33], [44,55] ],
[0, 1, 2],
[ [66], [77], [nil,99] ],
4
].transpose_rows

# => [
#   [2, 3, 6, 7, 11, 0, 66, 4],
#   [2, 3, 6, 7, 22, 0, nil, 4],
#   [2, 4, 6, 8, 33, 1, 77, 4],
#   [2, 5, 6, 9, 44, 2, nil, 4],
#   [2, 5, 6, 9, 55, 2, 99, 4]
# ]
``````
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download