30

I have the following:

value = 42  
array = ["this","is","a","test"]

how can I convert that to get this

{ "this" => { "is" => { "a" => { "test" => 42 } } } }

the array is always flat.

Thank you!

Mauricio
  • 5,854
  • 2
  • 28
  • 34
  • 1
    Now that's an insane data structure... would it happen to have any justification? –  Feb 23 '11 at 18:15
  • 2
    @delnan "hi.i.am.some.kind.of.path=value" to be merged in an existing yaml hash dump. – Mauricio Feb 23 '11 at 18:24
  • 1
    @delnan Another example would be to eager load a bunch of chained tables specified by an "array" like `join1:join2:join3:column1`. So I would need to `eager_load(join1: {join2: :join3})` – mlt May 18 '18 at 20:43

1 Answers1

107

Try this:

array.reverse.inject(value) { |assigned_value, key| { key => assigned_value } }
#=> {"this"=>{"is"=>{"a"=>{"test"=>42}}}}
Joshua Pinter
  • 45,245
  • 23
  • 243
  • 245
Marcos Crispino
  • 8,018
  • 5
  • 41
  • 59
  • The most difficult part of this was figuring out how to phrase my question on SO. "Nested" was the turning point ;) – Tobias J Jun 02 '14 at 02:02
  • 1
    You have achieved what I have been trying to achieve in about 50 lines less than my best attempt LOL. – OBCENEIKON Mar 09 '17 at 17:26
  • Somebody needs to explain how this magic works. Been trying to do this unsuccessfully for 60 minutes. – Joshua Pinter May 06 '21 at 20:04
  • Okay, I'll explain for myself and others. Firstly, this is clever in its simplicity. Using `reverse` and `inject` it first creates a Hash with the last `key` ("test") and the final value (42). It then takes that Hash and assigns it to the second last `key` ("a") and keeps going until it reaches the first `key` in the original Array. The result is a perfectly nested Hash. Nice one! – Joshua Pinter May 06 '21 at 20:19