String to hash

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

···

--
Posted via http://www.ruby-forum.com/.

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)

···

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 } } } }

Jens -- <jens@carroll.de> writes:

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 :-/).

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}}}}

···

Thanks
Jens
--
Posted via http://www.ruby-forum.com/\.

--
Brian Adkins
http://www.lojic.com/

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!

···

--
Posted via http://www.ruby-forum.com/\.

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.

···

On Tue, Dec 9, 2008 at 8:33 PM, Brian Adkins <lojicdotcom@gmail.com> wrote:

Jens -- <jens@carroll.de> writes:

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 :-/).

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

Oh sorry! Dave ... I have your book :slight_smile:

···

--
Posted via http://www.ruby-forum.com/.