2010-08-18 1 views
14

Ich habe eine Reihe von großen Dateien, in denen ich alle außer der letzten Zeile in jeder Datei verarbeiten möchte. Wenn die Dateien klein waren, konnte ich auf eine TraversableLike umbauen und nutzen die „init“ -Methode, z.B .:alle außer dem letzten Artikel von einem Scala Iterator (A.k.a.Iterator.init)

lines.toList.init 

Aber die Dateien sind groß, so muss ich Dinge als Iterator halten. Gibt es eine einfache Möglichkeit, etwas wie "init" auf einen Iterator zu bekommen? Ich betrachte die folgende, aber ich bin nicht sicher, es funktioniert immer:

lines.takeWhile(_ => lines.hasNext) 
+2

Was 'lines' ist? –

Antwort

14

Sie sich auf takeWhile zuerst die nächste Zeile greifen, und überprüfen dann, um zu sehen, ob es eine andere Linie ist. Im Standard-Iterator funktioniert das so. Und für einen bestimmten Iterator erwarte ich, dass es immer funktionieren sollte, wenn es jemals funktioniert.

Wenn es jemals fehlschlägt, müssen Sie das Ergebnis zwischenspeichern. Sie könnten Ihren eigenen Iterator machen, dass dies der Fall ist, oder, noch einfacher (wenn dieser Code nicht dringend leistungskritische ist):

lines.sliding(2).map(_.head) 

-Test dies wie folgt:

List(1,2,3,4,5).iterator.sliding(2).map(_.head).toList 

Sie dies nicht tun müssen sich auf takeWhile oder eine andere Methode verlassen, die sich auf eine bestimmte Weise verhält; Wenn sliding nicht unterbrochen ist, wird das obige Verhalten auftreten.

+0

Schön! Ich musste es ein wenig anstarren, um zu sehen, warum es funktioniert, aber es scheint weniger hackisch als meine Lösung. =) – Steve

3

Wenn Sie die ersten zwei Zeilen überspringen möchten, und legen Sie die letzten 4 Sie mit

List(1, 2, 3).toIterable.drop(1).dropRight(1) 

laufen könnte Wenn Sie bereits ein IterableLike haben

il.drop(1).dropRight(1) 
+0

'List (1, 2, 3) .iterator.dropright (1)' ergibt 'error: Wert dropRight ist kein Mitglied von Iterator [Int]'. Soweit ich das beurteilen kann, gibt es, genau wie 'init', keinen' dropRight' auf Iterator. – Steve