#ruby #group-by #ruby-hash
#ruby #группировка по #ruby-хэш
Вопрос:
У меня есть следующий массив
ages = [["a", 15],["b", 16], ["c", 15], ["d", 16], ["e", 17], ["f", 20]]
Я должен создать хэш с возрастом в качестве значений, чтобы он выглядел так
{15 => ["a","c"], 16=> ["b","d]....}
когда я запускаю метод group_by:
puts ages.group_by {|list| list[1]}
это то, что я получаю:
{15=>[["a", 15], ["c", 15]], 16=>[["b", 16], ["d", 16]], 17=>[["e", 17]], 20=>[["f", 20]]}
Я был бы очень признателен, если бы вы могли уточнить, как сделать это более чистым и получить значения в виде массива имен с одинаковым возрастом.
Ответ №1:
ages = [["a", 15],["b", 16], ["c", 15], ["d", 16], ["e", 17], ["f", 20]]
Вы можете упростить свой первый шаг:
ages.group_by(amp;:last)
#=> {15=>[["a", 15], ["c", 15]],
# 16=>[["b", 16], ["d", 16]],
# 17=>[["e", 17]],
# 20=>[["f", 20]]}
Затем вам нужно только преобразовать значения в нужные массивы:
ages.group_by(amp;:last).transform_values { |arr| arr.map(amp;:first) }
#=> {15=>["a", "c"],
# 16=>["b", "d"],
# 17=>["e"],
# 20=>["f"]}
Когда
arr = [["a", 15], ["c", 15]]
например,
arr.map(amp;:first)
#=> ["a", "c"]
См. раздел Hash#transform_values .
Ответ №2:
Первое, что приходит на ум, это
irb(main):012:0> ages.group_by {|e| e[1]}.map {|k, v| [k, v.map(amp;:first)]}.to_h
=> {15=>["a", "c"], 16=>["b", "d"], 17=>["e"], 20=>["f"]}
Здесь мы сопоставляем хэш с парами ключ-значение, сопоставляем значения каждой пары с первыми элементами, а затем преобразуем пары обратно в хэш.
Комментарии:
1. Это действительно полезно! Спасибо. Как вы сказали, должен быть более короткий путь, но с моей точки зрения это тоже здорово.
2. Да, зная Ruby, есть лучший способ, но, по крайней мере, это поможет вам начать. Мы посмотрим, что появится в потоке позже.