2015-05-03 15 views
5

Ich möchte eine elegante Pipeline zum Konvertieren einer Texteingabe in eine JSON-Ausgabe erhalten. Die Strömung sollte in etwa so gehen:Idiomatische (funktionale) Dateiverarbeitungspipeline in Scala

(input file)    // concatenated htmls and url 
Collection[String]  // unit: line 
Collection[String,String] // unit: url, html doc 
Collection[MyObj]   // unit: parsed MyObj 
(output file)    // json representation of parsed objects 

Derzeit ich dies für Schleifen mit verschachtelten tun, aber ich möchte dies in einem funktionalen Stil schreiben. Gibt es eine Standardmethode dafür oder typische Bibliotheken, die ich mir ansehen sollte? Hinweis: Die Daten sind ziemlich groß, daher kann ich sie nicht vollständig im Speicher haben.

+0

Ich denke, 'Collection [MyObj]' sollte als JSON-Array gedruckt werden? Hast du eine bestehende Lösung dafür? – stholzm

+0

@stholzm ja genau. Ich habe eine Funktion, um den JSON eines einzelnen 'MyObj' zu berechnen, aber dann wickle ich ihn in' [,] 'in den for-Schleifen. – mitchus

+0

klingt so, als ob Sie nach einer Bibliothek suchen, die den Inhalt eines JSON-Arrays als 'Iterable' oder anderweitig träge darstellt. Alles andere klingt machbar, aber ich habe keine Ideen. Jemand hat eine Idee? – stholzm

Antwort

2

Vielleicht können Sie Scalaz-Stream verwenden. Die Bibliothek bietet Kompositionalität, Ausdruckskraft, Ressourcensicherheit und Geschwindigkeit zur Verarbeitung von IO. Außerdem verwendet es sofortigen Speicher, der für die Handhabung großer Datenmengen sehr nützlich sein wird. Hier ist Github dafür:

https://github.com/scalaz/scalaz-stream

Youtube darüber reden:

https://www.youtube.com/watch?v=GSZhUZT7Fyc

https://www.youtube.com/watch?v=nCxBEUyIBt0

+0

Das sieht sehr interessant aus ... Auch verlinkt von dieser Seite: [Machines] (https://github.com/ekmett/machines/) – mitchus

+0

"Streaming Parsing" ist aber immer noch auf der Roadmap. Nicht sicher, wie der JSON-Teil der Frage ausgeführt wird. – stholzm

+0

Ich benutze diese Bibliothek in meinem Projekt, es sieht fantastisch aus, wenn man riesige Datenmengen verarbeitet und parallel verarbeitet. Ich denke nicht, dass es schwierig ist, es in die JSON-Bibliothek wie Argonaut (http://argonaut.io/) zu integrieren. Es kann es auf praktische Weise serialisieren und deserialisieren. –

0

ich in der Regel für Comprehensions für solche Aufgaben verwenden, um mit scala-Arm für Ressourcen Management (AutoClosable, Closeable usw.).

Viele Scala-Tutorials verwenden for { s <- Source.fromFile(...).getLines() }, aber es ist eine gute Möglichkeit, Ressourcenlecks zu erreichen, da Source nicht automatisch geschlossen wird.

Mit scala-Arm es sieht aus wie:

import resource._ 

for { source <- managed(Source.fromFile(...)) 
     target <- managed(Files.newBufferedWriter(...)) } { 
    for { rawLine <- source.getLines 
     line = rawLine.trim() if !rawLine.startsWith("#") 
     (url, html) <- parseString(line) 
     json <- toJsonOpt(html) } { 
    // actual action 
    target.write(s"$url\t$json\n") 
    } 
} 

Wenn Sie kompliziertere Pipeline benötigen, können Sie scalaz-Stream verwenden können, strom, Funken oder eine andere Bibliothek für die Definition tatsächliche Pipeline-DAG und starten Sie die Ausführung.

Verwandte Themen