2016-07-19 21 views
3

Ich bin ziemlich vertraut mit dem Modul Ruby Enumerable, oder zumindest so dachte ich. Nehmen Sie den folgenden Code-Schnipsel:Warum Map Enumerable Rückgabewert nicht erwartet Wert

names = [ "Donald", "Daisy", "Daffy" ] 

new_empty_array = [] 

new_names_array = names.map do |name| 
    new_empty_array << name 
end 

puts new_names_array.inspect 
# prints [["Donald", "Daisy", "Daffy"], ["Donald", "Daisy", "Daffy"], ["Donald", "Daisy", "Daffy"]] 

Ich weiß, ich bin nicht map mit richtig, aber ich war eine Lektion zum Ruby enumerables und kam in diesem Beispiel lehrt, wenn ein Schüler map aus testet. Der Rückgabewert des Schaufel-Operators (<<) ist das Array, nachdem ein Element hinzugefügt wurde. Sollte nicht das Ergebnis stattdessen sein:

[["Donald"], ["Donald", "Daisy"], ["Donald", "Daisy", "Daffy"]] 

Es scheint, dass die gesamte Schleife Prozesse und der endgültige Rückgabewert der Schaufel Operators verarbeitet werden? Was gibt?

+1

Ist 'first_names' sein soll' names'? – squiguy

Antwort

5

Das Ergebnis von map, in Ihrem Fall, ist ein Array, das mehrfach aus Referenzen auf das gleiche Array new_empty_array besteht. Sie erstellen nicht drei verschiedene Arrays, sondern modifizieren dasselbe Array im map-Block.

Um die Ausgabe zu erhalten Sie erwarten, was Sie tun müssen:

new_names_array = first_names.map do |name| 
    (new_empty_array << name).dup 
end 

Als Randbemerkung, Sie diesen Code verwenden könnten, was liegt näher, als den Code oben ist, für den Ausgang Sie wünschen:

(1..first_names.size).map do |num| 
    first_names.take(num) 
end 
#=> [["Donald"], ["Donald", "Daisy"], ["Donald", "Daisy", "Daffy"]] 
+0

Lassen Sie mich das klarstellen, der Rückgabewert für jede Iteration ist 'new_empty_array' und da die letzte Iteration der' .map' ein Array mit 3 Elementen zurückgibt, wird von der Map 'new_empty_array' im letzten Zustand zurückgegeben mal –

+0

@AndrewKim 'new_empty_array' ist ein Verweis auf ein Array, und Sie verweisen Verweis auf es in map und damit am Ende mit 3 Referenzen auf es als Array - alle 3 Referenzen zeigen auf das gleiche physikalische Array, das am Ende der Iteration 3 hat Elemente –

0
new_names_array = first_names.map do |name| 
    name 
end 

["Donald", "Daisy", "Daffy"] geben würde.

Jedes Element von first_names gibt einen Wert an das neue Array zurück, das von map erstellt wurde, aber stattdessen geben Sie für jedes Element ein neues Array new_empty_array zurück.

Dieses Objekt ist << dreimal und am Ende hat die drei Namen, also 3 x 3 Elementen:

[new_empty_array, new_empty_array, new_empty_array] = [["Donald", "Daisy", "Daffy"], ["Donald", "Daisy", "Daffy"], ["Donald", "Daisy", "Daffy"]] 
+0

@the Tin Man, thnx wieder für die Bearbeitung, Sie müssen eine Menge Zeit in die Korrektur von nicht Englisch sprechenden Menschen wie mich investieren – peter

+0

Mai gemeint sein 'nicht Englisch schreiben Leute' ;-) –