Groovyで改行コードを含む文字列の分割と結合
インデントを変更するをやる前に、Rubyのmap()とjoin()が、Groovyだと
どうなるかの確認をする。
やりたこと
改行文字を含む文字列を行ごとに加工して、再び元の文字列に戻したい
Rubyの場合
Rubyでは、map()とjoin()を使って簡単に加工が出来る。
Rubyのソース
test =<<"EOS" 1 aaaaa 2 bbbbb 3 ccccc 4 ddddd 5 eeeee 6 fffff 7 ggggg EOS
Rubyの結果
p "1)" p test test.map{ |line| p line } p "2)" result = test.map{ |line| line.gsub(" ",":") }.join("") p result
"1)" "1 aaaaa\n2 bbbbb\n3 ccccc\n4 ddddd\n5 eeeee\n6 fffff\n7 ggggg\n" "1 aaaaa\n" "2 bbbbb\n" "3 ccccc\n" "4 ddddd\n" "5 eeeee\n" "6 fffff\n" "7 ggggg\n" "2)" "1:aaaaa\n2:bbbbb\n3:ccccc\n4:ddddd\n5:eeeee\n6:fffff\n7:ggggg\n"
Groovy
これをGroovyでやろうとして、map()を試す。
test.map{line -> line.replaceAll(" ",":") }.join("")
文字列のmap()はないので、例外になる。
Caught: groovy.lang.MissingMethodException: No signature of method: java.lang.String.map() is applicable for argument types:
リストを返せばいのだから、map()をcollect()にして試す。
result = test.collect{line -> println line }
これだと文字単位に分割されてしまう。
1 a a a a a 2 b b b b b 3 c c c c c 4 d d d d d 5 e e e e e 6 f f f f f 7 g g g g g
ならば、eachLine()で行ごとに分割すればどうだ。
test.eachLine{line -> line.replaceAll(" ",":") }.join("")
これはコレクションになってないから、join()が例外・・・
Caught: groovy.lang.MissingMethodException: No signature of method: java.lang.String.join() is applicable for argument types:
行ごとに分割して、かつ、コレクションにする必要があるから、こうなるのか
test.split("\n").toList().collect{line -> println line }
1 aaaaa 2 bbbbb 3 ccccc 4 ddddd 5 eeeee 6 fffff 7 ggggg
これなら、行単位に分割できてるし、コレクションだからjoin()できるだろう
result = test.split("\n").toList().collect{line -> line.replaceAll(" ",":") }.join("") println result
1:aaaaa2:bbbbb3:ccccc4:ddddd5:eeeee6:fffff7:ggggg
ぬぅぉ・・・改行コードで分割したから、改行コードがなくなるのか
join("\n")でくっつければいいのか
result = test.split("\n").toList().collect{line -> line.replaceAll(" ",":") }.join("\n") println result
1:aaaaa 2:bbbbb 3:ccccc 4:ddddd 5:eeeee 6:fffff 7:ggggg
できた
join()を使わいで、eachLine()だとこうかな。
retStr = "" test.eachLine{line -> retStr += line.replaceAll(" ",":") + "\n" } println retStr |<< >|| 1:aaaaa 2:bbbbb 3:ccccc 4:ddddd 5:eeeee 6:fffff 7:ggggg
結論
Groovyでは、以下のようにする。
Groovy
String.split("\n").toList().collect{line -> ほげほげ }.join("\n")
Ruby
String.map(){|line| ほげほげ }join("")
添削歓迎
ここ間違ってるよ
こうした方がGroovyらしくないか?
などなど
方法は、コメント、トラックバック、はてブ、Twitter @orange_clover宛 で、お願いしまます。
実行環境
- OS:Windows XP
- Groovy Version: 1.6.5
- JVM: 1.6.0_12
- Ruby: 1.8.7 (2009-06-12 patchlevel 174) [i386-mswin32]
Groovyの詳細についてはJavadocと以下の書籍を参考にしている。
Dierk Konig、Andrew Glover、Paul King、、Guillaume Laforge、Jon Skeet、杉浦 孝、櫻井 正樹、須江 信洋、関谷 和愛、佐野 徹郎、寺沢 尚史
しばらくすれば2nd Editionが出るはず
問題自体は第2版のもの。rubyと似てる部分も多いので、ヒントにもなる。
写経でもいいが自分で考えるために他言語の例をGroovyで置き換えてる。
Groovyイン・アクションを読むならあった方が便利かな。