Groovyで文字列を最大nバイトに切り詰める
文字列を最大nバイトに切り詰める。n文字ではなく、nバイト。
ただし、マルチバイトの中途半端な状態(上位1バイトだけなど)は出力しない。
stripIndent()の行末版ってところだろうか。
コード
def takeNbytes(str, n) { buf = '' str = str.toList().each { c -> if ( buf.getBytes().size() + c.getBytes().size() <= n ) { buf += c } } return buf } println takeNbytes("あいうえお", 2) println takeNbytes("あいうえお", 3) println takeNbytes("あいうえお", 4) println takeNbytes("あいうえお", 5) println takeNbytes("あいうえお", 6) println takeNbytes("abcdef", 5)
実行結果
[D:\workspace\groovy_SandBox]groovy Q065_文字列を最大nバイトに切り詰める.groovy あ あ あい あい あいう abcde
疑問
each のなかでbreakってできないのかな?
抜ける場合はreturn?
そういえば今まで、メソッド名をtake_nbytesのようにRubyレシピのままで書いてたな。
(C言語ユーザでもあるので特に違和感はない。)
Groovy風に2単語目を大文字でtakeNbytesにしてみた。
Groovyistだとどう名付けるだろう。
添削
id:toby55kij
UTF-8だと結果は異なりますね
環境
[oc@centos5 Groovy]$ file Q065_UTF8.groovy Q065_UTF8.groovy: UTF-8 Unicode text >|| -環境変数 >|| [oc@centos5 Groovy]$ env|grep LANG LANG=ja_JP.UTF-8 LANGUAGE=ja_JP.UTF-8
実行結果
[oc@centos5 Groovy]$ groovy Q065_UTF8.groovy あ あ あ あい abcde
(/・_・\)アチャ-・・
文字コードなんて嫌いだ。
いや、単なる考慮不足です。。。。
eachを(手続き的な)制御構造と考えるとbreakが欲しくなるけど, Collectionの各要素に対する(関数型の)操作だから逆にbreakは意味ない. 例えば「全要素並列に引数のクロージャを適用」という実装もあり得るわけで, その時にはbreakなんて意味ないですもんね. と考えればいいんじゃないですか?
「(関数型の)操作だから」というの感覚がまだないんだよね。。。
並列でアウトというのは例は納得。
ちょっと書き換えてみました。Groovyではfor()の書き方がJavaとはちょっと異なります。
https://gist.github.com/1044702
def takeNbytes(str, n) { buf = '' for (s in str) { if ( buf.bytes.size() + s.bytes.size() > n) break buf += s } buf } println takeNbytes("あいうえお", 2) println takeNbytes("あいうえお", 3) println takeNbytes("あいうえお", 4) println takeNbytes("あいうえお", 5) println takeNbytes("あいうえお", 6) println takeNbytes("abcdef", 5)
forの書き方も違ったのか。軽くスルーしてた。
添削歓迎
ここ間違ってるよ
こうした方がGroovyらしくないか?
などなど
方法は、コメント、トラックバック、はてブ、Twitter @orange_clover宛 で、お願いしまます。
実行環境
- OS:Windows XP
- Groovy Version: 1.8.0
- JVM: 1.6.0_26
『プログラミングGroovy 』に向けて、環境を1.8.0にした
過去の記事と比較するために、できるだけ同じ組み合わせ(Groovy:1.6.5,JVM:1.6.0_12)でやってたけど
最新で動かなきゃ意味ないからね。
Groovyの詳細についてはJavadocと以下の書籍を参考にしている。
Dierk Konig、Andrew Glover、Paul King、、Guillaume Laforge、Jon Skeet、杉浦 孝、櫻井 正樹、須江 信洋、関谷 和愛、佐野 徹郎、寺沢 尚史
Amazonでご確認ください。
問題自体は第2版のもの。rubyと似てる部分も多いので、ヒントにもなる。
写経でもいいが自分で考えるために他言語の例をGroovyで置き換えてる。
Groovyイン・アクションを読むならあった方が便利かな。