Issue #6669 has been updated by david_macmahon (David MacMahon).


Please ignore my previous comment; I see that you want a new Hash rather than replacing the keys/values of the existing Hash.  I guess you want a more efficient alternative to:

max_score = Hash[score.map {|k,v| [k, v.max]}]

Since you want to create a new Hash from an existing object, how about a Hash::map factory method:

class Hash
  def self.map(other, &block)
    other.inject({}) do |h, (k, v)|
      new_k, new_v = *block.call(k, v)
      h[new_k] = new_v
      h
    end
  end
end

Note that "other" doesn't even need to be a Hash (e.g. it could be an Array of two element Arrays).  In fact, this:

Hash.map([ [key, value], ... ]) {|*kv| kv}

would be equivalent to:

Hash[ [ [key, value], ... ] ]

Perhaps if Hash::map is not given a block, the behavior could be as if the "{|*kv| kv}" block had been given.
----------------------------------------
Feature #6669: A method like Hash#map but returns hash
https://bugs.ruby-lang.org/issues/6669#change-29509

Author: yhara (Yutaka HARA)
Status: Feedback
Priority: Normal
Assignee: matz (Yukihiro Matsumoto)
Category: core
Target version: 2.0.0


=begin
Given a hash h, h.map returns an array(alist), but sometimes I hope it returned a hash.

Example:

  class Hash
    def apply(&block)
      self.inject({}) do |h, (k, v)|
        new_k, new_v = *block.call(k, v)
        h[new_k] = new_v
        h
      end
    end
  end
  
  score = {
    taro: [1,3,2], 
    jiro: [3,5,8,4], 
    saburo: [2,9]
  }
  max_score = score.apply{|k,v| [k, v.max]}
  #=> {taro: 3, jiro: 8, saburo: 9}
  p max_score[:taro]
  #=> 3

I'm not thinking "apply" is a perfect name for this. Maybe "hash_map" is better
(we already have "flat_map").
=end



-- 
http://bugs.ruby-lang.org/