Reputation: 3779
I would like to destructure a nested data structure using only block arguments.
The data (simplified for this example) is like this:
response = [
["James", { species: "cat", age: "4" }],
["Sandy", { species: "dog", age: "7" }],
["Horse", { species: "man", age: "34" }]
]
I can't find a syntax valid for destructuring this using only block arguments. I imagined it might be this, combining the nested-array destructuring style with named keyword arguments:
response.map do |name, (species:, age:)|
"#{name}: #{species}, #{age}"
end
but that gives a syntax error.
Obviously there are plenty of other ways to extract the necessary data e.g. using non-nested keyword arguments:
response.map do |name, data|
proc { |species:, age:|
"#{name}: #{species}, #{age}"
}.(data)
end
or
response.map do |name, data|
species, age = data.values_at(:species, :age)
"#{name}: #{species}, #{age}"
end
or the very obvious
response.map do |name, data|
"#{name}: #{data[:species]}, #{data[:age]}"
end
but I'd love to have it in the block arguments, because it appeals to my sense of elegant code. Any ideas?
Upvotes: 5
Views: 1100
Reputation: 198324
|name, species:, age:|
works (because of the way keyword arguments are handled). It obviously won't work in the general case, but due to the way keyword arguments work, an array whose last element is a hash cleanly corresponds to a parameter list.
Upvotes: 5