Может быть, есть более краткий способ сделать это, но я решил просто пойти прямым путем:
input = [ [38, "s", "hum"],
[38, "t", "foo"],
[38, "t", "bar"],
[45, "s", "hum"],
[45, "t", "ram"],
[52, "s", "hum"],
[52, "t", "cat"],
[52, "t", "dog"]
]
output = {}
# I'll talk through the first iteration in the comments.
input.each do |outer_key, inner_key, value|
# Set output[38] to a new hash, since output[38] isn't set yet.
# If it were already set, this line would do nothing, so
# output[38] would keep its previous data.
output[outer_key] ||= {}
# Set output[38]["s"] to a new array, since output[38]["s"] isn't set yet.
# If it were already set, this line would do nothing, so
# output[38]["s"] would keep its previous data.
output[outer_key][inner_key] ||= []
# Add "hum" to the array at output[38]["s"].
output[outer_key][inner_key] << value
end
Итак, часть, которую вы на самом деле используете, все приведено в порядок:
output = {}
input.each do |outer_key, inner_key, value|
output[outer_key] ||= {}
output[outer_key][inner_key] ||= []
output[outer_key][inner_key] << value
end