9

I learned from Access nested hash element specified by an array of keys)

that if i have a array

array = ['person', 'age']

and I have a nested hash

hash = {:person => {:age => 30, :name => 'tom'}}

I can get the value of of age by using

array.inject(hash, :fetch)

But How would I then set the value of :age to 40 with the array of keys?

3 Answers 3

11

You can get the hash that contains the last key in the array (by removing the last element), then set the key's value:

array.map!(&:to_sym) # make sure keys are symbols

key = array.pop
array.inject(hash, :fetch)[key] = 40

hash # => {:person=>{:age=>40, :name=>"tom"}}

If you don't want to modify the array you can use .last and [0...-1]:

keys = array.map(&:to_sym)

key = keys.last
keys[0...-1].inject(hash, :fetch)[key] = 40
Sign up to request clarification or add additional context in comments.

2 Comments

@CarySwoveland Thanks, I overlooked that. I also added an alternate solution if it's important to preserve the array.
Still not testing! If you don't want to modify array, keys = array.map(&:to_sym); key = keys.last.... (Ah, yes, it's pop. I had shift on the brain.)
0

You could use recursion:

def set_hash_value(h, array, value)
  curr_key = array.first.to_sym
  case array.size
  when 1 then h[curr_key] = value
  else set_hash_value(h[curr_key], array[1..-1], value)
  end
  h
end

set_hash_value(hash, array, 40)
  #=> {:person=>{:age=>40, :name=>"tom"}}

Comments

0

You can consider using the set method from the rodash gem in order to set a deeply nested value into a hash.

require 'rodash'

hash = { person: { age: 30, name: 'tom' } }

key = [:person, :age]
value = 40

Rodash.set(hash, key, value)

hash
# => {:person=>{:age=>40, :name=>"tom"}}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.