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

(/・_・\)アチャ-・・
文字コードなんて嫌いだ。
いや、単なる考慮不足です。。。。

id:yamadamasaki

eachを(手続き的な)制御構造と考えるとbreakが欲しくなるけど, Collectionの各要素に対する(関数型の)操作だから逆にbreakは意味ない. 例えば「全要素並列に引数のクロージャを適用」という実装もあり得るわけで, その時にはbreakなんて意味ないですもんね. と考えればいいんじゃないですか?

「(関数型の)操作だから」というの感覚がまだないんだよね。。。
並列でアウトというのは例は納得。


id:toby55kij

ちょっと書き換えてみました。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宛 で、お願いしまます。

実行環境

プログラミング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で置き換えてる。




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

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




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

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