2012年6月7日木曜日

XtendによるCSV集計サンプルコード

Xtendで、CSVファイルの内容をカラム毎に集計する、サンプルプログラムを書きました。会社の朝Xtend勉強会のお題で、その回答例として書いてみたものです。

package example
import com.google.common.io.Files
import java.io.File
import java.nio.charset.Charset
class CsvCalculator {
def static void main(String[] args) {
val total = new CsvCalculator().calculate('file.csv')
println(total)
}
def calculate(String file) {
readLines(file).map[s| s.toRecord].reduce[base, r| base + r]
}
def private readLines(String file) {
Files::readLines(new File(file), Charset::forName('utf-8'))
}
def private toRecord(String line) {
val ss = line.split(',')
new Record(Integer::valueOf(ss.get(0)), Long::valueOf(ss.get(1)))
}
}
@Data class Record {
int count
long volume
def operator_plus(Record r) {
new Record(count + r.count, volume + r.volume)
}
}

以下がポイントでしょうか。
  1. 行コレクションに対する map/reduce を、クロージャで書いている
  2. 行からRecordオブジェクトへの変換を、Extension methodで書いている
  3. Recordの足し込みを、"+"演算子オーバロードで書いている

ありきたりの内容ですが、Javaプログラマ向けの最初の練習問題としては、まぁまぁかな?