Ruby: What is the easiest method to update Hash values?

后端 未结 5 1817
無奈伤痛
無奈伤痛 2020-12-12 19:14

Say:

h = { 1 => 10, 2 => 20, 5 => 70, 8 => 90, 4 => 34 }

I would like to change each value v to foo(v

相关标签:
5条回答
  • 2020-12-12 19:37

    Rails (and Ruby 2.4+ natively) have Hash#transform_values, so you can now do {a:1, b:2, c:3}.transform_values{|v| foo(v)}

    https://ruby-doc.org/core-2.4.0/Hash.html#method-i-transform_values

    If you need it to work in nested hashes as well, Rails now has deep_transform_values(source):

    hash = { person: { name: 'Rob', age: '28' } }
    
    hash.deep_transform_values{ |value| value.to_s.upcase }
    # => {person: {name: "ROB", age: "28"}}
    
    0 讨论(0)
  • 2020-12-12 19:39

    You can use update (alias of merge!) to update each value using a block:

    hash.update(hash) { |key, value| value * 2 }
    

    Note that we're effectively merging hash with itself. This is needed because Ruby will call the block to resolve the merge for any keys that collide, setting the value with the return value of the block.

    0 讨论(0)
  • 2020-12-12 19:39

    This will do:

    h.each {|k, v| h[k] = foo(v)}
    
    0 讨论(0)
  • 2020-12-12 19:42

    There's a couple of ways to do it; the most straight-forward way would be to use Hash#each to update a new hash:

    new_hash = {}
    old_hash.each do |key, value|
      new_hash[key] = foo(value)
    end
    
    0 讨论(0)
  • 2020-12-12 19:50

    The following is slightly faster than @Dan Cheail's for large hashes, and is slightly more functional-programming style:

    new_hash = Hash[old_hash.map {|key, value| key, foo(value)}]
    

    Hash#map creates an array of key value pairs, and Hash.[] converts the array of pairs into a hash.

    0 讨论(0)
提交回复
热议问题