はじめに
こんにちは、Go界の加東大介です。今週にわかにLTSVというビッグウェーブが訪れましたね。
- Labeled Tab-separated Values
- Labeled Tab Separated Valuesノススメ
- 【今北産業】3分で分かるLTSV業界のまとめ【LTSV】
- LTSV FAQ - LTSV って何? どういうところが良いの?
- LTSV のもうひとつのメリット、あるいは、プログラムでログを出力する際に気をつけるべきこと
乗っかるべくGo用のreader/writerを書きました。ビックウェーブに乗っかったエントリということで。自分としては今回のポイントはGoでLTSV用のライブラリを書いたことよりも、テストをdrone.ioでやってることだと思います。
goltsv
最初はよく仕様を読まないで書き始めてencoding/csvを使ってreaderだけ殴り書きしたら、mattnさんに誤りの指摘を頂いたのと修正パッチをpull request頂いたのでmergeしました。mattnさん、どうもありがとうございます!その後、writerも追加しました。 概ね、encoding/csvと同様の実装となっています。
サンプル
reader
readerは読み込んだLTSVをmap[string]string
の形にします。
package main import ( "bytes" "fmt" goltsv "github.com/ymotongpoo/goltsv" ) func main() { // データ data := ` egg:たまご ham:ハム bread:パン gyoza:ぎょうざ ramen:ラーメン sushi:すし yakiniku:焼肉 yamanashi:山梨 tokyo:東京 okinawa:沖縄 hokkaido:北海道 ` b := bytes.NewBufferString(data) // Read LTSV data into map[string]string reader := goltsv.NewReader(b) records, err := reader.ReadAll() if err != nil { panic(err) } // dump for i, record := range records { fmt.Printf("===== Data %d\n", i) for k, v := range record { fmt.Printf("\t%s --> %s\n", k, v) } } }
こんなかんじでデータがとれますね
% go run reader_example.go ===== Data 0 bread --> パン egg --> たまご ham --> ハム ===== Data 1 ramen --> ラーメン gyoza --> ぎょうざ sushi --> すし yakiniku --> 焼肉 ===== Data 2 yamanashi --> 山梨 tokyo --> 東京 hokkaido --> 北海道 okinawa --> 沖縄
writer
writerのほうはmap[string]string
をLTSV形式にして吐き出します。
package main import ( "fmt" "bytes" goltsv "github.com/ymotongpoo/goltsv" ) func main() { data := []map[string]string { {"Python": "3.3.0", "Ruby": "2.0 rc2", "Perl": "5.16.2"}, {"spam": "foo", "egg": "bar", "ham": "buz"}, {"sauce": "ソース", "salt": "しお", "sugar": "さとう", "vinegar": "す"}, } b := &bytes.Buffer{} writer := goltsv.NewWriter(b) err := writer.WriteAll(data) if err != nil { panic(err) } fmt.Printf("%v", b.String()) }
こんなかんじでデータを書き出せます。
% go run writer_example.go Ruby:2.0 rc2 Python:3.3.0 Perl:5.16.2 ham:buz egg:bar spam:foo vinegar:す sugar:さとう sauce:ソース salt:しお
今後
LTSVの仕様で特に触れてはいませんが、Goのmapの仕様だと、ラベルが増えた場合にwriterから吐き出すとフィールドの順序が変わる可能性があって、そのへんは気にした方がいいのかどうかというのが微妙なところです。 とりあえずGitHubに公開しているので、Pull Requestが来てから考えればいいか、と思ってとりあえずこのまま。