Как мне изменить массив, когда я повторяю его в Ruby?

88

Я только изучаю Ruby, так что извиняюсь, если это слишком новичок для здесь, но я не могу понять это из книги о кирке (вероятно, просто недостаточно внимательно читаю). В любом случае, если у меня есть такой массив:

arr = [1,2,3,4,5]

... и я хочу, скажем, умножить каждое значение в массиве на 3, я разработал это, выполнив следующие действия:

arr.each {|item| item *= 3}

... не дадут мне то, что я хочу (и я понимаю, почему, я не изменяю сам массив).

Я не понимаю, как изменить исходный массив из блока кода после итератора. Я уверен, это очень просто.

Брэд
источник

Ответы:

140

Используйте mapдля создания нового массива из старого:

arr2 = arr.map {|item| item * 3}

Используйте map!для изменения массива на месте:

arr.map! {|item| item * 3}

Посмотрите, как это работает онлайн: ideone

Марк Байерс
источник
2
Если вам действительно нужно изменить каждый элемент, использование карты определенно будет более элегантным, imho.
fresskoma
2
А если вы хотите изменить сам массив, используйте карту! вместо этого
Йоанн Ле Туш
18

Чтобы напрямую изменить массив, используйте arr.map! {|item| item*3}. Чтобы создать новый массив на основе оригинала (что часто предпочтительнее), используйте arr.map {|item| item*3}. На самом деле, я всегда дважды думаю перед использованием each, потому что обычно есть функция более высокого порядка, например map, selectили она injectделает то, что я хочу.

Чак
источник
Что делать, если вы не хотите выполнять операцию перечисления? Что, если вы просто хотите что-то arr.map!{ destructive_op}изменить навсегда arr?
яркая звезда
1
@TrevorAlexander: Я не понимаю, что вы имеете в виду. Возможно, стоит задать настоящий вопрос с подробностями и прочим.
Чак
Я должен об этом подумать. Какие деструктивные операции над структурами не перечислить, кроме очень узкой модификации элементов?
яркая звезда
@TrevorAlexander: Мне все еще трудно понять. Если вы не можете посмотреть содержимое структуры, вы не можете преобразовать ее содержимое. Похоже, вы не заинтересованы в изменении структуры, а вместо этого просто хотите присвоить переменную, но я могу неправильно понять.
Чак
5
arr.collect! {|item| item * 3}
Джефф Ричардсон
источник