# String to hash

**URL:** <https://www.ruby-forum.com/t/string-to-hash/155149>\
**Category:** Ruby\
**Created:** [December 8, 2008, 6:51pm UTC](https://www.ruby-forum.com/t/string-to-hash/155149 "2008-12-08T18:51:20Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![jc71229](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/bb73d2/32.png) [@jc71229](https://www.ruby-forum.com/u/jc71229)\
**Post date:** [December 8, 2008, 6:51pm UTC](https://www.ruby-forum.com/t/string-to-hash/155149/1 "2008-12-08T18:51:20Z")

</div>

Hi All,

I am in the need of a method that does the following:

get 2 arguments a string and an integer (int\_val).  
The string has the following form “a.b.c.d”

the method should return a nested hash like that:

{ :a =\> { :b =\> { :c =\> { :d =\> int\_val } } } }

Hmmmm I am not rubyist enough to solve that elegant (or not at all :-/).

Thanks  
Jens

---

<div class="post-metadata">

**Author:** ![jc71229](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/bb73d2/32.png) [@jc71229](https://www.ruby-forum.com/u/jc71229)\
**Post date:** [December 8, 2008, 7:02pm UTC](https://www.ruby-forum.com/t/string-to-hash/155149/2 "2008-12-08T19:02:28Z")

</div>

On Dec 8, 2008, at 11:44 AM, Jens – wrote:

> I am in the need of a method that does the following:
> 
> get 2 arguments a string and an integer (int\_val).  
> The string has the following form “a.b.c.d”
> 
> the method should return a nested hash like that:
> 
> { :a =\> { :b =\> { :c =\> { :d =\> int\_val } } } }

How about

def nested\_hash(string, val)  
string.split(/./).reverse.inject(val) { |accum, val| { val.to\_sym  
=\> accum } }  
end

p nested\_hash(“a.b.c.d”, 123)

---

<div class="post-metadata">

**Author:** ![jc71229](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/bb73d2/32.png) [@jc71229](https://www.ruby-forum.com/u/jc71229)\
**Post date:** [December 8, 2008, 7:27pm UTC](https://www.ruby-forum.com/t/string-to-hash/155149/3 "2008-12-08T19:27:02Z")

</div>

> def nested\_hash(string, val)  
> string.split(/./).reverse.inject(val) { |accum, val| { val.to\_sym  
> =\> accum } }  
> end
> 
> p nested\_hash(“a.b.c.d”, 123)

Hmmmmmm … that wasn’t as hard as I expected it.  
Anyway I am impressed how fast that has been solved.

Thanks a lot David!

---

<div class="post-metadata">

**Author:** ![jc71229](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/bb73d2/32.png) [@jc71229](https://www.ruby-forum.com/u/jc71229)\
**Post date:** [December 8, 2008, 7:28pm UTC](https://www.ruby-forum.com/t/string-to-hash/155149/4 "2008-12-08T19:28:11Z")

</div>

Oh sorry! Dave … I have your book 🙂

---

<div class="post-metadata">

**Author:** ![jc71229](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/bb73d2/32.png) [@jc71229](https://www.ruby-forum.com/u/jc71229)\
**Post date:** [December 9, 2008, 8:40pm UTC](https://www.ruby-forum.com/t/string-to-hash/155149/5 "2008-12-09T20:40:54Z")

</div>

Jens – [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) writes:

> Hmmmm I am not rubyist enough to solve that elegant (or not at all :-/).

Dave’s solution is a good one & “idiomatic Ruby”, and it should be  
efficient since it spends much time in C code.

The following is another perspective that may or may not be clearer to  
you depending on your comfort level with recursion:

require ‘pp’

def tail list  
list[1…-1]  
end

def nested\_hash list, val  
return val if list.empty?  
{ list.first.to\_sym =\> nested\_hash(tail(list), val) }  
end

pp nested\_hash(“a.b.c.d”.split(‘.’), 7)

==\> {:a=\>{:b=\>{:c=\>{:d=\>7}}}}

---

<div class="post-metadata">

**Author:** ![jc71229](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/bb73d2/32.png) [@jc71229](https://www.ruby-forum.com/u/jc71229)\
**Post date:** [December 15, 2008, 3:11pm UTC](https://www.ruby-forum.com/t/string-to-hash/155149/6 "2008-12-15T15:11:12Z")

</div>

On Tue, Dec 9, 2008 at 8:33 PM, Brian A. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
wrote:

> > { :a =\> { :b =\> { :c =\> { :d =\> int\_val } } } }
> > 
> > Hmmmm I am not rubyist enough to solve that elegant (or not at all :-/).
> 
> Dave’s solution is a good one & “idiomatic Ruby”, and it should be  
> efficient since it spends much time in C code.

Sorry to answer after so long, but I wanted to give another version:

irb(main):059:0\> def nested\_hash s, i  
irb(main):060:1\> hash = Hash.new {|h,k| h[k] =  
Hash.new(&h.default\_proc)}  
irb(main):061:1\> terms = s.split(“.”)  
irb(main):062:1\> temp = terms[0…-2].inject(hash) {|acc,val|  
acc[val.to\_sym]}  
irb(main):063:1\> temp[terms[-1].to\_sym] = i  
irb(main):064:1\> hash  
irb(main):065:1\> end  
=\> nil  
irb(main):066:0\> nested\_hash “a.b.c.d”, 55  
=\> {:a=\>{:b=\>{:c=\>{:d=\>55}}}}

I am so fond of the arbitrarily nested hash construct :-).

Jesus.
