From: Fredrik Date: 2009-04-30T12:25:06+09:00 Subject: Re: Hash#map On 29 Apr, 21:39, James Gray wrote: > On Apr 29, 2009, at 1:00 AM, Fredrik wrote: > > > Is there any good reason why Hash#map does not give back a Hash (Ruby > > 1.8 but same in 1.9 as far as I know)? > > It wouldn't make sense for Hash#map to return a Hash since you are not   > required to transform it into key-value pairs: > >  >> {1 => "one", 2 => "two"}.map { |k, v| "#{k} is #{v}" } > => ["1 is one", "2 is two"] > > > I often find myself writing > > these kind of things: > > > newhash = oldhash.inject({}) { |h,(k,v)| h[k] = some_operation(v); h } > > 1.9 adds each_with_object() for this very usage.  You don't want the   > return value of the block to carry forward, but instead the object you   > started with.  That's what each_with_object() does.  So your code   > becomes the following in Ruby 1.9: > > newhash = oldhash.each_with_object({}) { |(k, v), h| >    h[k] = some_operation(v) > > } > > Hope that helps. > > James Edward Gray II Thanks! It's not a very big improvement over inject though. I don't see the use of Hash#map -> Array so if it was up to me, Hash#map would give a Hash. If one really wants an Array it seems more reasonable to use something like hash.to_a{|k,v| "#{k} is #{v}" } Maybe it's just me, but when I read "map" I am thinking "map this block to each element and give back the same structure" (i.e. Array#map gives an Array and Hash#map gives a Hash). (I know map is just an alias for collect, but I never understood why "collect" is a good name for this method.)