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宛 で、お願いしまます。



実行環境





Groovyの詳細についてはJavadocと以下の書籍を参考にしている。




Dierk Konig、Andrew Glover、Paul King、、Guillaume Laforge、Jon Skeet、杉浦 孝、櫻井 正樹、須江 信洋、関谷 和愛、佐野 徹郎、寺沢 尚史

しばらくすれば2nd Editionが出るはず




問題自体は第2版のもの。rubyと似てる部分も多いので、ヒントにもなる。
写経でもいいが自分で考えるために他言語の例をGroovyで置き換えてる。




青木 峰郎、後藤 裕蔵、高橋 征義、まつもと ゆきひろ

価格: ¥ 2,940
価格は記載時点のものです。購入前にAmazonでご確認ください。




Groovyイン・アクションを読むならあった方が便利かな。

Rubyレシピブックは「ほんたった」で立ててる