string to hash

J

Jens --

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
 
D

Dave Thomas

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)
 
J

Jens --

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!
 
B

Brian Adkins

Jens -- said:
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}}}}
 
J

Jesús Gabriel y Galán

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.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,983
Messages
2,570,187
Members
46,747
Latest member
jojoBizaroo

Latest Threads

Top