1

I need to transform ["a", "b", "c", "d"] to {:a => {:b => {:c => "d" }}} ?

Any ideas ?

Thanks

1
  • 1
    I'd be a little careful: how would you know that it should be converted to {:a => {:b => {:c => "d" }}} rather than {:a => :b, :c => :d}? Commented Sep 9, 2010 at 23:37

4 Answers 4

4

funny

ruby-1.8.7-p174 > ["a", "b", "c", "d"].reverse.inject{|hash,item| {item.to_sym => hash}}
 => {:a=>{:b=>{:c=>"d"}}}
Sign up to request clarification or add additional context in comments.

Comments

3

I like it:

class Array
  def to_weird_hash
    length == 1 ? first : { first.to_sym => last(length - 1).to_weird_hash }
  end
end

["a", "b", "c", "d"].to_weird_hash

What do you think?

4 Comments

What version of ruby is this valid for?
OK. I'm getting undefined method from in both 1.8.7 and 1.9.2
I'm doing it now with irb and it's not working, before I did it in script/console. Apparently the method Array#from doesn't exist... :S
Sounds like it is a ROR Monkeypatch.
2

If you need to do it for exactly 4 elements, it's easy enought to just write it out (and quite readable too)

>> A=["a", "b", "c", "d"]
=> ["a", "b", "c", "d"]
>> {A[0].to_sym => {A[1].to_sym => {A[2].to_sym => A[3]}}}
=> {:a=>{:b=>{:c=>"d"}}}

Otherwise, this will work for variable length arrays

>> ["a", "b", "c", "d"].reverse.inject(){|a,e|{e.to_sym => a}}
=> {:a=>{:b=>{:c=>"d"}}}
>> ["a", "b", "c", "d", "e", "f"].reverse.inject(){|a,e|{e.to_sym => a}}
=> {:a=>{:b=>{:c=>{:d=>{:e=>"f"}}}}}

3 Comments

I need it with more than one element.
@retro, not sure what you mean by more than one element. I added a way to do it with variable length arrays
I meant I have more than one element in input array. Also nice solution.
0

I figured it out with help on IRC.

x = {}; a[0..-3].inject(x) { |h,k| h[k.to_sym] = {} }[a[-2].to_sym] = a[-1]; x

Second way with recursive (better)

def nest(a)
  if a.size == 2
    { a[0] => a[1] }
  else
    { a[0] => nest(a[1..-1]) }
  end
end

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.