Ich möchte auf CSV-Dateien in Scala stark typisiert zugreifen. Zum Beispiel, wenn ich jede Zeile des CSV lese, wird es automatisch analysiert und als Tupel mit den entsprechenden Typen dargestellt. Ich könnte die Typen vorher in einer Art Schema angeben, das an den Parser übergeben wird. Gibt es Bibliotheken, die dafür existieren? Wenn nicht, wie kann ich diese Funktionalität selbst implementieren?
Produkt-Sammlungen scheint Ihren Anforderungen gerecht zu werden:
%Vor% Produkt-Sammlungen verwendet opencsv unter der Haube.
A CollSeq3
ist ein IndexedSeq[Product3[T1,T2,T3]]
und auch ein Product3[Seq[T1],Seq[T2],Seq[T3]]
mit etwas Zucker. Ich bin Autor von Produkt-Sammlungen .
Hier ist ein Link zu die io Seite des scaladoc
Product3 ist im Wesentlichen ein Tupel von Arity 3.
Produkt-Sammlungen scheint Ihren Anforderungen gerecht zu werden:
%Vor% Produkt-Sammlungen verwendet opencsv unter der Haube.
A Iterator[Array[String]]
ist ein Iterator.map
und auch ein collect
mit etwas Zucker. Ich bin Autor von Produkt-Sammlungen .
Hier ist ein Link zu die io Seite des scaladoc
Product3 ist im Wesentlichen ein Tupel von Arity 3.
Ich habe einen stark typisierten CSV-Helfer für Scala erstellt, object-csv . Es ist kein vollwertiges Framework, aber es kann leicht angepasst werden. Damit kannst du das machen:
%Vor%Wo Person ist Fallklasse, wie folgt definiert:
%Vor%Lesen Sie mehr darüber in GitHub oder in meinem blog Beitrag darüber.
Ich habe meine eigene Idee entwickelt, um das Endprodukt stark zu typisieren, mehr als die Lesephase selbst. Wie bereits erwähnt, könnte es besser als erste Stufe mit etwas wie Apache CSV gehandhabt werden, und Stufe 2 könnte das sein, was ich getan habe . Hier ist der Code, den Sie willkommen sind. Die Idee ist, den CSVReader [T] mit Typ T zu typisieren. Bei der Konstruktion müssen Sie dem Leser auch ein Factor-Objekt vom Typ [T] liefern. Die Idee dabei ist, dass die Klasse selbst (oder in meinem Beispiel ein Hilfsobjekt) das Konstruktionsdetail entscheidet und dieses somit vom eigentlichen Lesen entkoppelt. Sie könnten implizite Objekte verwenden, um den Helper herumzuführen, aber ich habe das hier noch nicht gemacht. Der einzige Nachteil ist, dass jede CSV-Zeile vom gleichen Klassentyp sein muss, aber Sie können dieses Konzept nach Bedarf erweitern.
%Vor%Als nächstes das Beispiel Helper Factory und Beispiel "Main"
%Vor%Beispiel-CSV (Registerkarte getrennt .. muss möglicherweise repariert werden, wenn Sie von einem Editor kopieren)
%Vor%Und schließlich der Autor (beachten Sie die Factory-Methoden erfordern dies auch mit "Makerow"
%Vor%Sie können kantan.csv verwenden, das genau zu diesem Zweck entwickelt wurde.
Stellen Sie sich vor, Sie haben folgende Eingabe:
%Vor%Mit kantan.csv könnten Sie den folgenden Code schreiben, um es zu parsen:
%Vor% Und Sie erhalten einen Iterator, bei dem jeder Eintrag vom Typ Array[String]
ist. Beachten Sie das Bit, bei dem die letzte Spalte in Ihrer CSV-Datei mehrere Typen umfassen kann. Dies wird jedoch bequem mit Vector
behandelt.
Dies geschieht auf eine absolut typsichere Art und Weise, ohne Reflektion, die zur Kompilierzeit überprüft wird.
Je nachdem, wie weit das Kaninchenloch reicht, gibt es auch ein formloses -Modul für die automatisierte Fallklasse und Sum-Typ-Ableitung, sowie Unterstützung für scalaz und Katzen Typen und Typklassen.
Vollständige Offenlegung: Ich bin der Autor von kantan.csv.
Wenn Sie die # und Typen von Feldern kennen, vielleicht so?:
%Vor%Dies wird komplizierter gemacht, als es aufgrund der nichttrivialen Zitationsregeln für CSV der Fall sein sollte. Sie sollten wahrscheinlich mit einem vorhandenen CSV-Parser beginnen, z. OpenCSV oder eines der Projekte namens scala-csv. (Es gibt am wenigsten drei .)
Dann enden Sie mit einer Art Sammlung von Saiten. Wenn Sie keine umfangreichen CSV-Dateien schnell lesen müssen, können Sie einfach versuchen, jede Zeile in jeden Ihrer Typen zu zerlegen und den ersten zu verwenden, der keine Ausnahme auslöst. Zum Beispiel
%Vor% Wenn Sie sie ziemlich schnell analysieren müssen und Sie nicht wissen, was da sein könnte, sollten Sie wahrscheinlich eine Art von Übereinstimmung (z. B. Regexes) für die einzelnen Elemente verwenden. So oder so, wenn eine Fehlermöglichkeit besteht, möchten Sie wahrscheinlich List
oder Left
oder so etwas wie Paketfehler verwenden.
Ich möchte auf CSV-Dateien in Scala stark typisiert zugreifen. Zum Beispiel, wenn ich jede Zeile des CSV lese, wird es automatisch analysiert und als Tupel mit den entsprechenden Typen dargestellt. Ich könnte die Typen vorher in einer Art Schema angeben, das an den Parser übergeben wird. Gibt es Bibliotheken, die dafür existieren? Wenn nicht, wie kann ich diese Funktionalität selbst implementieren?
Dies wird komplizierter gemacht, als es aufgrund der nichttrivialen Zitationsregeln für CSV der Fall sein sollte. Sie sollten wahrscheinlich mit einem vorhandenen CSV-Parser beginnen, z. OpenCSV oder eines der Projekte namens scala-csv. (Es gibt am wenigsten drei .)
Dann enden Sie mit einer Art Sammlung von Saiten. Wenn Sie keine umfangreichen CSV-Dateien schnell lesen müssen, können Sie einfach versuchen, jede Zeile in jeden Ihrer Typen zu zerlegen und den ersten zu verwenden, der keine Ausnahme auslöst. Zum Beispiel
%Vor% Wenn Sie sie ziemlich schnell analysieren müssen und Sie nicht wissen, was da sein könnte, sollten Sie wahrscheinlich eine Art von Übereinstimmung (z. B. Regexes) für die einzelnen Elemente verwenden. So oder so, wenn eine Fehlermöglichkeit besteht, möchten Sie wahrscheinlich Try
oder Option
oder so etwas wie Paketfehler verwenden.
Ich habe einen stark typisierten CSV-Helfer für Scala erstellt, object-csv . Es ist kein vollwertiges Framework, aber es kann leicht angepasst werden. Damit kannst du das machen:
%Vor%Wo Person ist Fallklasse, wie folgt definiert:
%Vor%Lesen Sie mehr darüber in GitHub oder in meinem blog Beitrag darüber.
Ich habe meine eigene Idee entwickelt, um das Endprodukt stark zu typisieren, mehr als die Lesephase selbst. Wie bereits erwähnt, könnte es besser als erste Stufe mit etwas wie Apache CSV gehandhabt werden, und Stufe 2 könnte das sein, was ich getan habe . Hier ist der Code, den Sie willkommen sind. Die Idee ist, den CSVReader [T] mit Typ T zu typisieren. Bei der Konstruktion müssen Sie dem Leser auch ein Factor-Objekt vom Typ [T] liefern. Die Idee dabei ist, dass die Klasse selbst (oder in meinem Beispiel ein Hilfsobjekt) das Konstruktionsdetail entscheidet und dieses somit vom eigentlichen Lesen entkoppelt. Sie könnten implizite Objekte verwenden, um den Helper herumzuführen, aber ich habe das hier noch nicht gemacht. Der einzige Nachteil ist, dass jede CSV-Zeile vom gleichen Klassentyp sein muss, aber Sie können dieses Konzept nach Bedarf erweitern.
%Vor%Als nächstes das Beispiel Helper Factory und Beispiel "Main"
%Vor%Beispiel-CSV (Registerkarte getrennt .. muss möglicherweise repariert werden, wenn Sie von einem Editor kopieren)
%Vor%Und schließlich der Autor (beachten Sie die Factory-Methoden erfordern dies auch mit "Makerow"
%Vor%Sie können kantan.csv verwenden, das genau zu diesem Zweck entwickelt wurde.
Stellen Sie sich vor, Sie haben folgende Eingabe:
%Vor%Mit kantan.csv könnten Sie den folgenden Code schreiben, um es zu parsen:
%Vor% Und Sie erhalten einen Iterator, bei dem jeder Eintrag vom Typ (Int, String, Either[Float, Boolean])
ist. Beachten Sie das Bit, bei dem die letzte Spalte in Ihrer CSV-Datei mehrere Typen umfassen kann. Dies wird jedoch bequem mit Either
behandelt.
Dies geschieht auf eine absolut typsichere Art und Weise, ohne Reflektion, die zur Kompilierzeit überprüft wird.
Je nachdem, wie weit das Kaninchenloch reicht, gibt es auch ein formloses -Modul für die automatisierte Fallklasse und Sum-Typ-Ableitung, sowie Unterstützung für scalaz und Katzen Typen und Typklassen.
Vollständige Offenlegung: Ich bin der Autor von kantan.csv.
Tags und Links scala csv tuples strong-typing