1

Using .flatten is a handy little trick to take an array of sub-arrays and turn it into a single array. For example: [[1,3],2,[5,8]].flatten => [1,3,2,5,8] You can even include nil [1,[2,nil],3].flatten will result in [1,2,nil,3].

This kind of method is very useful when nesting a .map method, but how would you account for an empty sub-array? For example: [1,[2,3],[],4].flatten would return [1,2,3,4]... but what if I need to keep track of the empty sub array maybe turn the result into [1,2,3,0,4] or [1,2,3,nil,4]

Is there any elegant way to do this? Or would I need to write some method to iterate through each individual sub-array and check it one by one?

2 Answers2

5

If you don't need to recursively check nested sub-arrays:

[1,[2,3],[],4].map { |a| a == [] ? nil : a }.flatten
eiko
  • 5,110
  • 6
  • 17
  • 35
  • This is a bit cleaner than what i had. I changed a == [] to a.any? but similar concept... For some reason I always overlook putting logic into my .map blocks. –  Feb 21 '17 at 20:04
  • 2
    @jkessluk won't a.any? choke on items which aren't arrays? – eiko Feb 21 '17 at 20:06
  • 1
    Yes, but I'm using this in a helper method where I've already ensured that the item passed through is an array. Otherwise, yes. You're correct. –  Feb 21 '17 at 20:10
2

First map the empty arrays into nils, then flatten

[1,2,[1,2,3],[]].map{|x| if x.is_a? Array and x.empty? then nil else x end}.flatten
Andrey Deineko
  • 51,333
  • 10
  • 112
  • 145
Coolness
  • 1,932
  • 13
  • 25