I am wondering why trying to convert this array to a hash causes an error:
[:a, [1,2,3]].to_h
=> TypeError: wrong element type Symbol at 0 (expected array)
Hash[ [:a, [1,2,3]] ]
=> ArgumentError: invalid number of elements (3 for 1..2)
The array hash two items. So it should be easily converted to a key/value pair, which is what a hash is.
I have a collection that looks like this:
[ [:a, [1,2,3]], [:b, [4,5,6]] ]
And I just want to make it an array of hashes:
[ [:a, [1,2,3]], [:b, [4,5,6]] ].collect {|collection| Hash[collection] }
=> ArgumentError: invalid number of elements (3 for 1..2)
Why cannot it not convert an array of two items into a key/value pair?
I could do something like this:
arr.collect {|item| { item[0] => item[1] } }
=> [{:a=>[1, 2, 3]}, {:b=>[4, 5, 6]}]
[]
once moreYou need an array of pairs, since one Hash
can contain many of those, and that feature is reflected in what its constructors accept. A single pair is an array with 2 elements.
Hash[ [:a, [1,2,3]] ]
This is a call to Hash.[]
with a single pair [:a, [1,2,3]]
.
To make it an array of pairs, wrap once more, getting [[:a, [1,2,3]]]
or
Hash[[[:a, [1,2,3]]]
# ↑↑↑
# ||\_pair
# |\_array of pairs
# \_call to Hash.[]
The amount of square brackets here is nauseating.
If your end goal is an array of hashes, each being a single pair, you could use destructuring in block arguments like so:
[ [:a, [1,2,3]], [:b, [4,5,6]] ].collect {|(a, b)| {a => b} }
This is literally the same thing you're suggesting at the end of your question, only without []
.
.to_h takes an array of multple key value pairs
[ [:a, [1,2,3]], [:b, [4,5,6]] ].to_h
=> {:a=>[1, 2, 3], :b=>[4, 5, 6]}
[ [:a, [1,2,3]] ].to_h
=> {:a=>[1, 2, 3]}
Hash[] takes a single key and value
Hash[:a, [1,2,3]]
=> {:a=>[1, 2, 3]}
.to_h expects each element in the array to be an array with 2 items. Hence if any item in the array is a not an array itself, it gives a type error.
[:a, [1,2,3]].to_h
TypeError: wrong element type Symbol at 0 (expected array)
Hash[] with a two arrays returns a hash with the first array as the key and the second array as the value, as it's expecting a single key and value.
Hash[ [:a, [1,2,3]], [:b, [4,5,6]] ]
=> {[:a, [1, 2, 3]]=>[:b, [4, 5, 6]]}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With