Wie ändere ich ein Array, während ich in Ruby darüber iteriere?

87

Ich lerne gerade Ruby und entschuldige mich, wenn dies zu neu für hier ist, aber ich kann das nicht aus dem Spitzhackenbuch herausarbeiten (wahrscheinlich nur nicht sorgfältig genug lesen). Wie auch immer, wenn ich ein Array wie dieses habe:

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

... und ich möchte beispielsweise jeden Wert im Array mit 3 multiplizieren. Ich habe Folgendes herausgefunden:

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

... wird mir nicht das bringen, was ich will (und ich verstehe warum, ich ändere das Array selbst nicht).

Was ich nicht verstehe, ist, wie man das ursprüngliche Array innerhalb des Codeblocks nach dem Iterator ändert. Ich bin sicher, das ist sehr einfach.

Brad
quelle

Antworten:

138

Verwenden Sie mapdiese Option , um ein neues Array aus dem alten zu erstellen:

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

Verwenden Sie map!diese Option, um das vorhandene Array zu ändern:

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

Sehen Sie, wie es online funktioniert: ideone

Mark Byers
quelle
2
Wenn Sie wirklich jedes Element ändern müssen, wäre die Verwendung von map definitiv eleganter, imho.
Fresskoma
2
Und wenn Sie das Array selbst ändern möchten, verwenden Sie map! stattdessen
Yoann Le Touche
17

Verwenden Sie zum direkten Ändern des Arrays arr.map! {|item| item*3}. Verwenden Sie, um ein neues Array basierend auf dem Original zu erstellen (was häufig vorzuziehen ist) arr.map {|item| item*3}. Tatsächlich denke ich immer zweimal darüber nach, bevor ich es benutze each, weil es normalerweise eine Funktion höherer Ordnung gibt map, selectoder injectdas macht, was ich will.

Futter
quelle
Was ist, wenn Sie keine Aufzählungsoperation ausführen möchten? Was ist, wenn Sie nur etwas tun möchten, um arr.map!{ destructive_op}sich dauerhaft zu ändern arr?
Heller Stern
1
@ TrevorAlexander: Ich bin nicht sicher, was du meinst. Es könnte sich lohnen, eine echte Frage mit Details und Dingen zu stellen.
Chuck
Ich muss darüber nachdenken. Welche destruktiven Operationen an Strukturen sind, abgesehen von sehr engen Elementmodifikationen, nicht aufzählbar?
Heller Stern
@ TrevorAlexander: Ich habe immer noch Schwierigkeiten zu verstehen. Wenn Sie den Inhalt einer Struktur nicht anzeigen können, können Sie den Inhalt nicht transformieren. Es hört sich so an, als ob Sie nicht daran interessiert sind, eine Struktur zu ändern, sondern nur eine Variable zuweisen möchten - aber ich könnte ein Missverständnis haben.
Chuck
5
arr.collect! {|item| item * 3}
Jeff Richardson
quelle