先日のどう書くをうけて

グルからメッセがきた。内容がおもろかったので転載します。

参考: http://d.hatena.ne.jp/nbqx69/20081018#p1

以下メッセのログ(改)。

13:04 mottsnite
def clo = {
  this.r=[]
  new File("data.csv").splitEachLine(/\t/){
    this.r<<[it[0],it[2],it[1],(it[3].isNumber())? it[3].toInteger()+1:it[3]]
  }
  return [
    this.r.first().join("\t"),
    this.r.tail().sort().collect(){it.join("\t")}.join("\n")
  ].join("\n")
}
println clo()

クロージャにまとめてみた・・。

13:05 nbqx69

おせわさまです!
ぼくも再帰で、とおもったんですが
短さ重視にしましたw

13:07 mottsnite

this.rは別にdef rでもよいね・・・。

13:08 nbqx69

printlnが一回ってのがかっこいいですね。

13:08 mottsnite

そそ、それがやりたかった。あと再利用

def clo = {f->
  def r=[]
  new File(f).splitEachLine(/\t/){
    r<<[it[0],it[2],it[1],(it[3].isNumber())? it[3].toInteger()+1:it[3]]
  }
  return [
    r.first().join("\t"),
    r.tail().sort().collect(){it.join("\t")}.join("\n")
  ].join("\n")
}
println clo("data.csv")

引数にしてみた+def rにしたw

13:10 nbqx69

sortがなければ、cliオプションのaとかnとかpとかつかいたかったんですけど… perl好きにはたまらんですよねw

13:11 mottsnite

ソートの

sort(){it[0].toInteger()}
it[0].toInteger()

って必要? ぁ、必要か。。

13:17 mottsnite

ぁ!

r.tail().sort().collect(){it.join("\t")}.join("\n")

r.tail().sort()*.join("\t").join("\n")
13:18 nbqx69

ん?
sort()* ??

13:18 mottsnite

*.
collectいらない・・

def clo = {f->
  def r=[]
  new File(f).splitEachLine(/\t/){
    r<<[it[0],it[2],it[1],(it[3].isNumber())? it[3].toInteger()+1:it[3]]
  }
  return [
    r.first().join("\t"),
    r.tail().sort(){it[0].toInteger()}*.join("\t").join("\n")
  ].join("\n")
}
println clo("data.csv")
13:22 nbqx69

*ってGIA本にもありますよね? 今さがしてるんですが・・
英語版pdfで

13:23 mottsnite

あったかな?

Book.list()*.delete()

って、Grailsの本(英語)にあったけど

new File(f).splitEachLine(/\t/)

で、

new File(f).text.trim().splitEachLine(/\t/)

にしないと、ファイルに要らない改行あると・・ヌルポ。。
だいぶ実用的になってきたw

13:28 nbqx69

ふははw
まだ*をさがしてるんですけど、

13:28 mottsnite

でもね・・・・。
汎用的ではない・・

13:29 nbqx69

認識としては再帰的にlistをみるって認識でいいんですか?

13:29 mottsnite

ぁ、*は、*と同じ意味だね。
と、わけのわからない説明
ワイルドカード

13:30 nbqx69

メソッドじゃなくてlist操作の[]とかと同じテイストのものってことですか?
すません。おしえて君で・・

13:31 mottsnite

うーん、
そこに食いつくと思わなかったので。。

コマンドの
cp -rf *
の * と同じ
という認識でしかない

13:31 nbqx69

あーわかりました!!

13:32 mottsnite

[1,2,3,4]*.hoge()

13:32 nbqx69

しかし
汎用的ではないとはいえ
printlnが1回はリファクタリング的には最高じゃないでしょうか
自分やりたくてもできなかったし…

13:35 mottsnite

性格的にアウトはまとめたくなるだけ・・・。
ってか、ゲンゾウさんのブログみて挑戦してみたが、
時間切れで挫折→uehajさんがぶろぐる→nbqx69がぶろぐる
→何だか悔しく。。。。
人のコードに乗っかってみたw
すまん、正直splitEachLineは知らなかった!

13:36 nbqx69

mottsniteさん、やっぱgroovyっぽいですね、というかmottsniteさんっぽいw
自分はrubylispっぽいw

13:37 mottsnite

ぉぉ、オレの"r"なんて微妙な変数が、まさにオレっぽいw
クロージャ渡せば汎用的w

def clo = {f,c->
  def r=[]
  new File(f).text.trim().splitEachLine(/\t/){ r<<c(it) }
  return [
    r.first().join("\t"),
    r.tail().sort(){it[0].toInteger()}*.join("\t").join("\n")
  ].join("\n")
}
println clo("data.csv",{[it[0],it[2],it[1],(it[3].isNumber())? it[3].toInteger()+1:it[3]]})
13:39 nbqx69

だんだんlispっぽくなってますよw

13:40 mottsnite

ぁ、、、微妙・・・だ、、ソートとか・・・
これでどうだ!引数増えた・・・

def clo = {f,c,skey->
  def r=[]
  new File(f).text.trim().splitEachLine(/\t/){ r<<c(it) }
  return [
    r.first().join("\t"),
    r.tail().sort(){it[skey]}*.join("\t").join("\n")
  ].join("\n")
}
println clo("data.csv",{[it[0],it[2],it[1],(it[3].isNumber())? it[3].toInteger()+1:it[3]]},0)

こうやって、コードって進化するのか・・・

13:43 nbqx69

なにげにクロージャの引数わたしとかgroovyっぽいですよね、
やっぱmottsniteさんっぽいです、なんつーかロジックのおもしろさ的な意味で。

13:45 mottsnite

ほほ!
このログ・・・ものすごいハイウエストのコメントに投稿しよかなw

13:46 nbqx69

うははw
だったらこのまま自分のなまえをnbqx69にして記事にしちゃいましょうか?

13:47 mottsnite

ぁぁ、それいいね。
おれの名前は mottsnite で・・

13:47 nbqx69

了解です、今日中のタスクにします!

13:47 mottsnite

よろしくぅー


ここまで。

この会話で感じたのですが、はじめはざくっと書いてだんだんgroovyっぽくしていく、groovyのグルーヴ感が出るようなコードにしていくような道場をどこか中部地方あたりの山間部(自分が行きやすいから)に開いたらいいと思います。

コードゴルフみたいなとこまでいくと、「おれがミスターXだ」とか「私が紅蜂さんやりたい」とか「特別なパターの材料をイノブタに探しあてるために会社休む」みたいなひとたちがでてくるので大変かもしれませんね。