Come posso modificare un array mentre sto iterando su di esso in Ruby?


88

Sto solo imparando Ruby quindi mi scuso se questo è troppo principiante per qui, ma non riesco a capirlo dal libro del piccone (probabilmente non sto leggendo abbastanza attentamente). Ad ogni modo, se ho un array come questo:

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

... e voglio, diciamo, moltiplicare ogni valore nell'array per 3, l'ho capito facendo quanto segue:

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

... non mi darà quello che voglio (e capisco perché, non sto modificando l'array stesso).

Quello che non capisco è come modificare l'array originale dall'interno del blocco di codice dopo l'iteratore. Sono sicuro che sia molto facile.

Risposte:


140

Utilizzare mapper creare un nuovo array da quello vecchio:

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

Utilizzare map!per modificare l'array in posizione:

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

Guardalo in linea: ideone


2
Se hai davvero bisogno di modificare ogni elemento, usare map sarebbe sicuramente più elegante, imho.
fresskoma

2
E se vuoi modificare l'array stesso usa map! invece
Yoann Le Touche

18

Per modificare direttamente l'array, utilizzare arr.map! {|item| item*3}. Per creare un nuovo array basato sull'originale (che spesso è preferibile), utilizzare arr.map {|item| item*3}. In effetti, ci penso sempre due volte prima dell'uso each, perché di solito c'è una funzione di ordine superiore come map, selecto injectche fa quello che voglio.


E se non si desidera eseguire un'operazione di enumerazione? E se volessi solo fare qualcosa come arr.map!{ destructive_op}cambiare in modo permanente arr?
stella luminosa

1
@TrevorAlexander: non sono sicuro di cosa intendi. Potrebbe valere la pena porre come una vera domanda con dettagli e cose.
Chuck

Ci dovrò pensare. Oltre alla modifica di elementi molto ristretta, quali operazioni distruttive sulle strutture non sono enumerabili?
stella luminosa

@TrevorAlexander: Sto ancora avendo difficoltà a capire. Se non puoi guardare il contenuto di una struttura, non puoi trasformarne il contenuto. Sembra che tu non sia interessato a modificare una struttura, e invece desideri solo assegnare una variabile, ma potrei essere frainteso.
Chuck

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.