Reputation: 4888
I have an array of strings of unknown length (but let's say up to 5). I have also an empty hash h = {}
and a value.
I want to transform the array and the value to hash like this:
val = 1
h = {}
a = ['a', 'b', 'c', 'd']
# result I want:
{
'a' => {
'b' => {
'c' => {
'd' => 1
}
}
}
}
What's important is that some of the keys might already exist (created in a loop iteration before). So I might have:
val = 2
h = {'a' => {'b' => {'c' => {'d' => 1}}}}
a = ['a', 'b', 'c', 'e']
# result I want:
{
'a' => {
'b' => {
'c' => {
'd' => 1,
'e' => 2
}
}
}
}
Any ideas on how to do that?
Upvotes: 0
Views: 256
Reputation: 211590
Once again, inject
to the rescue:
def dredge(hash, list, value = nil)
# Snip off the last element
*list, tail = list
# Iterate through the elements in the path...
final = list.inject(hash) do |h, k|
# ...and populate with a hash if necessary.
h[k] ||= { }
end
# Add on the final value
final[tail] = value
hash
end
This could be improved a little depending on how resilient you need it to be on things like zero-length lists and so on.
Here it is applied:
h = {}
a = ['a', 'b', 'c', 'd']
dredge(h, a, 1)
# => {"a"=>{"b"=>{"c"=>{"d"=>1}}}}
h = {'a' => {'b' => {'c' => {'d' => 1}}}}
a = ['a', 'b', 'c', 'e']
dredge(h, a, 2)
# => {"a"=>{"b"=>{"c"=>{"d"=>1, "e"=>2}}}}
Upvotes: 4