3

If we have a hash and we want to update one of the values or keys we can easily use the .update method like the following

def foo(params)
    params+=1
end

hsh = {:a=>1,:b=>2,:c=>3}

hsh.update(hsh) do |key,oldVal|
    foo(oldVal)
end

p hsh

However suppose a new hash, and I want to copy its properties into another hash and add one to the value. How would I exactly do this? Here is my attempt

def foo(params)
    params+=1
end
new_hsh = {:a=>1,:b=>2,:c=>3}
hsh = {}
hsh.update(new_hsh) do |key,value,newVal|
    newVal = foo(value)
end

p hsh

Which outputs {:a=>1,:b=>2,:c=>3}. So it is copying new_hsh, but not updating the value.

According to docs

Adds the contents of other_hash to hsh. If no block is specified, entries with duplicate keys are overwritten with the values from other_hash, otherwise the value of each duplicate key is determined by calling the block with the key, its value in hsh and its value in other_hash.

So it is copying like the docs say.. but how can I update it?

Thanks

EDIT

tried

def foo(params)
    params+=1
end
new_hsh = {:a=>1,:b=>2,:c=>3}
hsh = {}
hsh.update(new_hsh) do |key,value,newVal|
    foo(newVal)
end

p hsh
bill
  • 378
  • 2
  • 9

2 Answers2

1

Dont pass in 3 parameters. Just pass in 2 like this. Iterate over each key, value pair of your new_hsh and set the key equal to the new value after being passed to the foo method and push into your hsh.

def foo(params)
params+=1
end
new_hsh = {:a=>1,:b=>2,:c=>3}
hsh = {}
new_hsh.each do |key,value|
    hsh[key] = foo(value)
end

p hsh
Robert
  • 86
  • 1
  • 5
  • Great, this does indeed work, how do i implement this using `.update` though? – bill Aug 29 '16 at 15:13
  • Try this question http://stackoverflow.com/questions/5215713/ruby-what-is-the-easiest-method-to-update-hash-values – Velocibadgery Aug 29 '16 at 16:53
  • My working example is the same as the suggested ones in that question. I just wanted to know if I can do this with `update`, with regards to a new hash. Is there any way to do so? – bill Aug 29 '16 at 17:09
1

Here is another answer. This works but also modifies the new_hsh. But you need to set the hsh = new_hsh before calling update on hsh.

def foo(params)
params+=1
end

new_hsh = {:a=>1,:b=>2,:c=>3}
hsh = new_hsh
hsh.update(hsh) do |key,value|
    hsh[key] = foo(value)
end

p hsh
Robert
  • 86
  • 1
  • 5