#arrays #ruby
#массивы #ruby
Вопрос:
У меня есть вложенный массив Ruby, подобный этому:
arr = [["Red", 2], ["Red", 1], ["Yellow", 0], ["Yellow", 2], ["Blue", 1]]
И я пытаюсь найти метод, который суммирует число (которое является вторым элементом в каждом мини-массиве) для похожих элементов, получая вложенный массив, подобный этому:
[["Red", 3], ["Yellow", 2], ["Blue", 1]]
Я пробовал циклы for и операторы if, но я не могу точно понять, как это сделать.
С не вложенным массивом вы могли бы просто использовать if
и .includes?
, но я не уверен, как это сделать с вложенным массивом.
Какие-нибудь мастера Ruby могут направить меня в правильном направлении?
Комментарии:
1. Я отредактировал ваши массивы, чтобы сделать их допустимыми объектами Ruby, а также присвоил переменную входному массиву. Последнее позволяет читателям ссылаться на эту переменную в ответах и комментариях без необходимости ее определения. Кроме того, эти изменения облегчают вырезание и вставку в тестовый код.
Ответ №1:
Обратите внимание, что это не массив и не допустимый ruby
["Red", 3], ["Yellow", 2], ["Blue", 1]
в любом случае попробуйте это
arr.group_by { |color, amount| color }
.map { |k, color_arr| [k, color_arr.map(amp;:last).inject(: )] }
=> [["Red", 3], ["Yellow", 2], ["Blue", 1]]
или начиная с ruby 2.4.0 и выше
arr.group_by { |color, amount| color }
.map { |k, color_arr| [k, color_arr.map(amp;:last).sum] }
Комментарии:
1. Спасибо! Я очень новичок в этом и действительно смог собрать его воедино! Отличное объяснение.
2. При желании,
arr.group_by(amp;:first)
иcolor_arr.sum(amp;:last)
…
Ответ №2:
arr.each_with_object(Hash.new(0)) {|(col,nbr),h| h[col] = nbr}.to_a
#=> [["Red", 3], ["Yellow", 2], ["Blue", 1]]
Обратите внимание на промежуточное вычисление:
arr.each_with_object(Hash.new(0)) {|(col,nbr),h| h[col] = nbr}
#=> {"Red"=>3, "Yellow"=>2, "Blue"=>1}
См. Hash::new .