Como modifico um array enquanto estou iterando sobre ele no Ruby?


88

Estou apenas aprendendo Ruby, então me desculpe se isso for muito novo por aqui, mas não consigo resolver isso no livro de picaretas (provavelmente não estou lendo com cuidado o suficiente). De qualquer forma, se eu tiver uma matriz como esta:

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

... e eu quero, digamos, multiplicar cada valor na matriz por 3, eu trabalhei fazendo o seguinte:

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

... não vai me dar o que eu quero (e eu entendo porque, não estou modificando o array em si).

O que eu não entendo é como modificar a matriz original de dentro do bloco de código após o iterador. Tenho certeza de que isso é muito fácil.

Respostas:


140

Use mappara criar uma nova matriz a partir da antiga:

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

Use map!para modificar a matriz no local:

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

Veja funcionando online: ideone


2
Se você realmente precisa modificar cada elemento, usar o mapa seria definitivamente mais elegante, imho.
fresskoma

2
E se você quiser modificar o próprio array, use map! em vez disso
Yoann Le Touche

18

Para modificar diretamente a matriz, use arr.map! {|item| item*3}. Para criar um novo array baseado no original (o que geralmente é preferível), use arr.map {|item| item*3}. Na verdade, sempre penso duas vezes antes de usar each, porque geralmente há uma função de ordem superior como map, selectou injectfaz o que eu quero.


E se você não quiser fazer uma operação de enumeração? E se você apenas quiser fazer algo como arr.map!{ destructive_op}mudar permanentemente arr?
estrela brilhante de

1
@TrevorAlexander: Não tenho certeza do que você quer dizer. Pode valer a pena fazer uma pergunta real com detalhes e outras coisas.
Chuck

Vou ter que pensar sobre isso. Além da modificação de elemento muito restrita, quais operações destrutivas em estruturas não são enumeráveis?
estrela brilhante de

@TrevorAlexander: Ainda estou tendo dificuldade em entender. Se você não pode olhar o conteúdo de uma estrutura, não pode transformar seu conteúdo. Parece que você não está interessado em modificar uma estrutura e, em vez disso, deseja apenas atribuir uma variável - mas posso estar enganado.
Chuck

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.