Zusammenfassung: Die grundlegende Frage hier war, ich habe herausgefunden, ob Sie einen Code-Block an ein Ruby-Array übergeben können, der den Inhalt dieses Arrays tatsächlich auf ein anderes Array reduziert, nicht auf ein einzelner Wert (wie inject ). Die kurze Antwort ist "Nein".
Ich akzeptiere die Antwort, die das sagt. Dank Squeegy für eine großartige Looping-Strategie, um Streifen aus einem Array zu bekommen.
Die Herausforderung: Die Elemente eines Arrays reduzieren, ohne sie explizit durchlaufen zu müssen.
Eingabe: Alle Ganzzahlen von -10 bis 10 (außer 0) werden nach dem Zufallsprinzip sortiert .
Die gewünschte Ausgabe: Ein Array, das Streifen positiver oder negativer Zahlen darstellt. Zum Beispiel repräsentiert ein -3 drei aufeinanderfolgende negative Zahlen. A 2 steht für zwei aufeinanderfolgende positive Zahlen.
Beispielskript:
%Vor%Beispielausgaben:
%Vor%Beachten Sie ein paar Dinge:
Hoffe, das ist klar!
Edit: Ich erkenne, dass solche Konstrukte als ablehnen! Durchlaufen das Array im Hintergrund. Ich schließe Schleifen nicht aus, weil ich eine gemeine Person bin. Nur um etwas über die Sprache zu lernen. Wenn eine explizite Iteration notwendig ist, ist das in Ordnung.
Seit Ruby 1.9 gibt es eine viel einfachere Möglichkeit, dieses Problem zu lösen:
%Vor%Enumerable.chunk gruppiert alle aufeinanderfolgenden Elemente eines Arrays zusammen mit dem Ausgang eines Blocks:
%Vor%Dies ist fast genau das, wonach OP fragt, außer dass die resultierenden Gruppen hochgezählt werden müssen, um das letzte Streifen-Array zu erhalten.
Nun, hier ist eine einzeilige Version, wenn Ihnen das mehr gefällt:
%Vor%Und wenn sogar spritzen ist zu schleimig für dich, hier ist ein wirklich alberner Weg:
%Vor%Aber ich denke, es ist ziemlich klar, dass Sie mit etwas viel einfacher dran sind:
%Vor%Zusätzlich dazu, dass die "loop" -Version viel einfacher zu verstehen und zu warten ist, läuft sie in etwa zwei Drittel der Zeit der inject-Version und etwa ein Sechstel der Zeit von eval / regexp.
PS: Hier ist eine weitere potentiell interessante Version:
%Vor%Dies verwendet zwei Durchgänge, indem zuerst ein Array von Streak-Arrays erstellt und dann das Array von Arrays in ein Array von vorzeichenbehafteten Größen konvertiert wird. In Ruby 1.8.5 ist das tatsächlich etwas schneller als die oben beschriebene Injection-Version (obwohl es in Ruby 1.9 etwas langsamer ist), aber die langweilige Schleife ist immer noch die schnellste.
Die Magie hier ist der Operator ^
xor.
Wenn also die letzte Zahl im Array auf der gleichen Seite wie die verarbeitete Zahl steht, fügen Sie sie dem Streifen hinzu, andernfalls fügen Sie sie dem Streifen-Array hinzu, um einen neuen Streifen zu beginnen. Beachten Sie, dass sine true ^ true
false
zurückgibt. Wir müssen den gesamten Ausdruck negieren.
Tags und Links ruby