Home > Mobile >  How to convert a string into a nested hash
How to convert a string into a nested hash

Time:09-16

I have a string foo.bar.baz with a value 'qux' that I want to convert to a nested hash like so:

{
  foo: {
    bar: {
      baz: 'qux'
    }
  }
}

How would I do this in a way that would allow for different string lengths? e.g. foo.bar or foo.bar.baz.qux

CodePudding user response:

First of all, you have to split the string. You can then use inject to build the structure. Because the hash is built from the inside out, we have to reverse the initial array:

'foo.bar.baz'.split('.')  #=> ["foo", "bar", "baz"]
             .reverse     #=> ["baz", "bar", "foo"]
             .inject('qux') { |memo, key| { key.to_sym => memo } }
#=> {:foo=>{:bar=>{:baz=>"qux"}}}

It might not be obvious how this works. On the first invocation, memo is 'qux' and key is 'baz'. The block turns this into {:baz=>'qux'} which then becomes the new memo.

Step by step:

memo                    key                result
--------------------------------------------------------------
'qux'                   'baz'                  {:baz=>'qux'}
{:baz=>'qux'}           'bar'           {:bar=>{:baz=>'qux'}}
{:bar=>{:baz=>'qux'}}   'foo'    {:foo=>{:bar=>{:baz=>'qux'}}}
  •  Tags:  
  • ruby
  • Related