Samstag, 4. Juni 2011

Convert a CSV File in Groovy, Java or Scala?

Last week I have simple task I must convert a simple CSV file into another CSV format. My first solution was a simple Groovy script. Then inforw sends me a Java solution, to show me that with Java it is no much more code then the Groovy implementation is. Today I wrote just for fun a solution in Scala, to see how the code looks in Scala. My favorite of the three implementations is at the moment the Groovy one. But I think the Scala implementation has the best readability. Below you see the three implementations.

I'm curious what you like, feel free for comments? And I would be glad if someone contributes even further implementation in Clojure, Python, Perl,… or even a better Scala, Java or Groovy implementation.

The Groovy Implementation:
new File("output.csv") withPrintWriter { out ->
new File("input.csv") splitEachLine(';') { fields ->
def name = fields[2]
def firstname = fields[1]
def kto = fields[3]
def blz = fields[4]
def amount = fields[5]
out.println "${name};${firstname} ${name};${kto};${blz};${amount}"
}
}

The Java Implementation:
import java.io.*;
public class CsvConvertor {
public static void main(String[] args) throws Exception {
FileWriter out = new FileWriter("output.csv");
BufferedReader in = new BufferedReader(new FileReader("input.csv"));
String line;
while ((line = in.readLine()) != null) {
String[] fields = line.split(";");
String name = fields[2];
String firstname = fields[1];
String kto = fields[3];
String blz = fields[4];
String amount = fields[5];
out.append(
String.format("%s;%s %1$s;%s;%s;%s%n",
name, firstname,kto, blz, amount));
}
out.close();
}
}

The Scala Implementation:
import io.Source._
import java.io._
object CsvConvertor extends Application {
val outputCsv = new FileWriter("output.csv")
val accounts = fromFile("input.csv") getLines() map (line => Account(line))
accounts foreach (account => outputCsv append (account toCsv))
outputCsv close
}
case class Account(line: String) {
val data = line split (';')
val firstname = data(1)
val lastname = data(2)
val kto = data(3)
val blz = data(4)
val amount = data(5)
def toCsv() =
"%s;%s %1$s;%s;%s;%s%n" format (lastname, firstname, kto, blz, amount)
}

Thanks @inforw for the discussion and the Java implementation.