Как мне изменить массив, когда я повторяю его в 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: Мне все еще трудно понять. Если вы не можете посмотреть содержимое структуры, вы не можете преобразовать ее содержимое. Похоже, вы не заинтересованы в изменении структуры, а вместо этого просто хотите присвоить переменную, но я могу неправильно понять.
Чак

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.