coorasse coorasse - 3 months ago 13
Ruby Question

How to flatten subarrays in Ruby?

I have the following structure

a = [['a', 'b', 'c'], ['d', 'e', 'f'], [['g', 'h', 'i'], ['l', 'm', 'n']]]


and I want to obtain the following:

[['a', 'b', 'c'], ['d', 'e', 'f'], ['g', 'h', 'i'], ['l', 'm', 'n']]


I've tried the following:

a.flatten => ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'l', 'm', 'n']

a.flatten(1) => ['a', 'b', 'c', 'd', 'e', 'f', ['g', 'h', 'i'], ['l', 'm', 'n']]


the solution I found, for now, is to change the initial structure to this format:

b = [[['a', 'b', 'c']], [['d', 'e', 'f']], [['g', 'h', 'i'], ['l', 'm', 'n']]]


and then call

b.flatten(1) => [['a', 'b', 'c'], ['d', 'e', 'f'], ['g', 'h', 'i'], ['l', 'm', 'n']]


but I could do this only because I was able to change how
a
was built. My question remains: how to obtain my desired result starting from
a
?

Answer
a.each_with_object([]) do |e, memo|
  e == e.flatten ? memo << e : e.each { |e| memo << e }
end
#⇒ [['a', 'b', 'c'], ['d', 'e', 'f'], ['g', 'h', 'i'], ['l', 'm', 'n']]