Deep Hash creation one liner

I was trying to create a hash { mountain: { river: { tree: 23 } } }using the below :

path = [:mountain, :river, :tree,23]
hash = {}
path.each_cons(2).to_a.reverse.inject(hash,:[]=)

=>

~> -:3:in `[]=’: wrong number of arguments (1 for 2) (ArgumentError)

~> from -:3:in `each’

~> from -:3:in `inject’

~> from -:3:in `’

I know why the error comes. But my question is - Is there any way to
send 2 arguments to the method :[]= ,by breaking the one argument
array using splat or something like that ?

[16] pry(main)> path.reverse.reduce({}){|s,v| v == path.last ? v : {v =>
s}
}

=> {:mountain=>{:river=>{:tree=>23}}}

You’re trying to use a Symbol argument which is a shorthand way to
create a block. If you want to pass more detailed instructions, pass a
block.

Or if you really want, you can redefine :[]=.to_proc.

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Nice solution! It led me to this, which is a little shorter:

> path = [:mountain, :river, :tree, 23]
 => [:mountain, :river, :tree, 23]
> path.reverse.reduce { |s,v| {v => s} }
 => {:mountain=>{:river=>{:tree=>23}}}

Quoting from
http://ruby-doc.org/core-2.0.0/Enumerable.html#method-i-reduce :

If you do not explicitly specify an initial value for memo,
then the first element of collection is used as the initial
value of memo.

Peace,
tiredpixel

On 10/10/2013 21:25, Michael F. wrote:

path = [:mountain, :river, :tree,23] hash = {}

– Michael F.
-----BEGIN PGP SIGNATURE-----
Version: GnuPG/MacGPG2 v2.0.20 (Darwin)
Comment: GPGTools - http://gpgtools.org
Comment: Using GnuPG with Thunderbird - http://www.enigmail.net/

iQEcBAEBAgAGBQJSVxLJAAoJEOFolTkanF7V/8gH/iS2dSxmhiMTbcHgrVCntEhG
iY9kKH5jpHdRUWeK65vuc8S05NTmCbAbTfTwwp/ii1MLugXNuCZ4eRk8jqdNdBtx
E+cEfpoTvcqD2IbJ2NUGJt7svUzsvqyE0OiNNkaeGATDnp6r0+0k75uMXKz/jmiS
bi5TANMKKM1lxcymYmodFwULb1VTaPhw5Vv4F8+ReVXUncDUzXrCajlTf/39OOF/
KmSTqREVRuKqdcBtHuX6hAQGVB/O5BF9XjaxtRbfkmOw84V9BaUkPPhC9xRkzsRa
hucEp8/bqErcu/KXLkv1oUzA2o9AyJVl+f4vd50F5V796uaC9AB1dywtgVhuB9c=
=u0KL
-----END PGP SIGNATURE-----

Joel P. wrote in post #1124210:

You’re trying to use a Symbol argument which is a shorthand way to
create a block. If you want to pass more detailed instructions, pass a
block.

Or if you really want, you can redefine :[]=.to_proc.

Yes something like that I also tried,But I also tried…but didn’t work.

path = [:mountain, :river, :tree,23]
hash = {}
path.each_cons(2).to_a.reverse.inject(&hash.method(:[]))

=>

~> -:3:in `[]’: wrong number of arguments (2 for 1) (ArgumentError)

~> from -:3:in `each’

~> from -:3:in `inject’

~> from -:3:in `’

Still I am not being able to pass the 2 arguments,for one argument it
should work. But for 2 argument,I don’t know the trick.

You’re missing the point.

Using a symbol is a shortcut way to use a predefined block. If you want
a block to do something different, then use a block, not a symbol.

This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.

| Privacy Policy | Terms of Service | Remote Ruby Jobs