AnApprentice
AnApprentice

Reputation: 110950

Append the results of a Ruby .map into an array?

I'm trying to build a items array. I'm looping through a CSV file and when i find matches expanding the list of items. See code below:

items = Array.new
csv.each_with_index do |row,i|
   items << ["a","b","c"].map {|x| row.to_s.gsub(/XXXXXXXXXX/, x.downcase)}
end
puts items.length

This is not returning to desired items array. Am I appended the results of map incorrectly to the array?

Upvotes: 2

Views: 5997

Answers (2)

Eric Duminil
Eric Duminil

Reputation: 54223

As a rule of thumb, if you're :

  • initializing an empty Array
  • iterating over elements, modifiying the array
  • returning the Array at the end

There's a Ruby Enumerable method to help you!

In this case, you could use flat_map and with_index :

csv = %w(1;2;3 4;5;6 7;8;9)

items = csv.flat_map.with_index do |row,i|
   ["a","b","c"].map {|x| row.to_s.gsub(/[159]/, x.downcase)}
end

p items
#=> ["a;2;3", "b;2;3", "c;2;3", "4;a;6", "4;b;6", "4;c;6", "7;8;a", "7;8;b", "7;8;c"]

Upvotes: 1

max pleaner
max pleaner

Reputation: 26758

Yes, you are doing it incorrectly here:

items << ["a","b","c"].map

Items would end up as a nested array. Here's an example of what's happening here:

arr = []
arr << [1].map { |x| x }
arr
# => [[1]]

Instead, you can use +=.

You can also use push if you use the splat operator:

arr = []
arr.push *["a","b","c"].map { |x| x }
arr
# => ["a", "b", "c"]

Upvotes: 6

Related Questions