-1

Hello all I'm new and I've been searching and can't find a clear answer to this question, I'm hoping this summarizes it:

a = {:a1 => "a1", :b1 => [] }

how would I add :c1 to the a hash and make it another hash, leading to an array, and add values to that array? I would like the return of the a hash to resemble:

=> {:a1 => "a1", :b1 => [], :c1 => {c2 => [0, 1]}
Artjom B.
  • 61,146
  • 24
  • 125
  • 222
  • Does "make it another hash" mean "add data to hash `a` by altering it" or does it mean "create a new hash that's `a` plus some other data"? – tadman Dec 18 '20 at 16:58

2 Answers2

3

Merging Hashes

One option among others is to use Hash#merge!. For example:

a = {:a1=>"a1", :b1=>[]}
a.merge!({:c1=>{:c2=>[0, 1]}})
#=> {:a1=>"a1", :b1=>[], :c1=>{:c2=>[0, 1]}}

Note that while parenthesis are often optional in Ruby, they're needed with Hash literals and #merge! to ensure the Hash to be merged is treated as an argument instead of a block by the parser/interpreter.

If you'd prefer to return a new Hash with the merged elements, then use Hash#merge instead. This will leave the original a untouched, while returning a copy of a merged with your Hash-literal argument.

Todd A. Jacobs
  • 81,402
  • 15
  • 141
  • 199
  • Note: There's no need for `{ ... }` inside of a method call, the last argument can be an implicit hash or keyword arguments. That is `f({ x: y, ... })` is equivalent to `f(x: y, ...)`. – tadman Dec 18 '20 at 16:56
2

In multiple steps:

a = { :a1 => "a1", :b1 => [] }
a[:c1] = {}
a[:c1][:c2] = []
a[:c1][:c2] << 0
a[:c1][:c2] << 1

a #=> { :a1 => "a1", :b1 => [], :c1 => { :c2 => [0, 1] } }

Or in one step:

a = { :a1 => "a1", :b1 => [] }
a[:c1] = { c2: [0, 1] }

a #=> { :a1 => "a1", :b1 => [], :c1 => { :c2 => [0, 1] } }
spickermann
  • 100,941
  • 9
  • 101
  • 131
  • This alters the `a` hash, if that's acceptable. If the intent is to make a new one, you'd have to at least `dup` it. – tadman Dec 18 '20 at 16:57