Search code examples
arraysrubyeachruby-2.0ruby-1.8.7

ruby .map! or each for modifying an array in place


I have the following:

article_results.keys do |key|
  article_results[key].map! do |a|
    a[:filename] = c.filename
    a[:sitename] = c.site_name
    a
  end
end

As I want to add to each element of each array within the hash dynamically, but for some reason a[:filename] and a[:sitename] are blank when they are used.

So I want to know if I should be using .each instead. Also I guess I'd like to know what's the main difference since they both can be used for side-effects.

I'm adding this as an extra fyi, I'm using ruby 1.8.7 so it would be nice to know how it differs between versions (1.8.7 - 1.9+) as well.

P.s. I know what the difference between .each and .map is, I'm asking specifically about .map!.


Solution

  • #map has a bit different semantics for hashes than it has for arrays (and i think it's not very consistent between versions of ruby). in general if you are looking for an array as a result of some operation - #map is your friend, however if you want hash as a result of some operation - you're better off with #reduce:

    article_results.reduce({}) do |hash, (key, value)|
      hash.merge(key => value.merge(filename: c.filename,
                                    sitename: c.sitename))
    end
    

    alternatively if you don't care how "functional" your code is, you can use #each:

    article_results.each do |key, value|
      article_results[key].merge!(filename: c.filename,
                                  sitename: c.sitename)
    end