2017-03-02 2 views
0

Ich habe versucht, diesen Code in Ruby auszuführen:Warum durchläuft nicht jeder Iterator das gesamte Array?

array=[1,2,3,4,5] 
array.each do |x| 
    puts array.length 
    puts "Downloading #{array.length} files" 
    array.pop 
end 

Ich habe:

5 
Downloading 5 files 
4 
Downloading 4 files 
3 
Downloading 3 files 

Ich verstehe nicht, warum ich nur drei Iterationen zu bekommen. Was mache ich falsch (abgesehen davon, dass keine while Schleife verwendet wird)?

+4

Mutieren Sie keine Aufzählungen während der Iteration. Diese Frage wurde Dutzende Male beantwortet. – mudasobwa

+0

Relevante Frage: [Wert des Array-Elements ändern, auf das in einer .each-Schleife verwiesen wird?] (http://stackoverflow.com/q/5646710/2620080) –

+0

Wenn Sie eine Erklärung zu dem, was Sie wollen, angeben, können wir Ihnen möglicherweise eine andere Lösung anbieten. –

Antwort

1

Was zuvor passiert war:

  1. array.length 5 ist
  2. x = 1 wird
  3. Array.shift verarbeitet (array.length 4)
  4. Arraylänge = 4
  5. x = 2 wird verarbeitet
  6. (3 array.length ist)
  7. Array.shift
  8. x = 3 wird
  9. verarbeitet
  10. Array.shift (array.length ist 2)

Jetzt gibt es keine weiteren Array-Elemente bis hin zu iterieren, weil die letzten 3 Items (3,4,5) werden geknallt.

Eine bessere Möglichkeit, zu tun ist, um das Array zu umkehren und verschiebt es

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

array.reverse.each do |x| 
    puts array.length 
    puts "Downloading #{array.length} files" 
    array.shift 
end 

Was ist jetzt passiert, jetzt das Array [5,4,3,2,1] ist. Jede Schleife verarbeitet das erste Element im Array, legt die Array-Länge fest und entfernt dann den Wert mit shift.

+1

Vielen Dank! Das ist eine Art Hilfe, die ich mir erhofft hatte! – xyzmg

0

Es ist Ursache, die Sie aus der array beginnen iterieren es bedeutet:

1 step: puts array[0] and you delete array[4] element(array => [1, 2, 3, 4]) 
2 step: puts array[1] and delete array[3] element(array => [1, 2, 3]) 

Wenn Sie jedes Element löschen möchten, nachdem sie zurückgebracht, können Sie es in vielen Varianten tun, einige davon:

array.reverse.each do |x| 
    puts "Downloading #{x} files" 
    array.pop 
end 

oder

array.size.times do 
    puts "Downloading #{array.pop} files" 
end 

Wenn Sie nicht wollen, leer array achtern bekommen er diese Iteration, können Sie einfach:

array.reverse.each do |x| 
    puts "Downloading #{x} files" 
end 
+0

Vielen Dank für Ihre Hilfe. – xyzmg

0

In Ihrer Funktion verringert array.pop die Länge Ihres Arrays. In letzter Zeile

3 
Downloading 3 files 

Ihre Array-Länge ist 3 und Ihre jede Schleife ist bereits laufen 3 mal. deshalb wird das nächste Element nicht iteriert. (Hier durchläuft jede Schleife nur 3 Elemente, weil die Länge Ihres Arrays 3 ist)

Verwandte Themen