入力行の行ごとのシャッフルをrubyでしたいと思ってぐぐってみたらなかったので、ちょっと書いてみた。
たとえば重複した文字列をなくするために sort foo.txt | uniq > bar.txt とかよくやると思うが、この時、bar.txtは正順になってしまっているのが困る場面がある。どんな時かといわれても困るが、とにかく綺麗に並んでいると困る時があるとする。これをランダムな並びに変えたいとおもってぐぐってみたらPerlだとList::Util::shuffleを使った書き方が出てくるのだが、Rubyだとそれっぽい書き方がみつからない。
外部のライブラリを使わず、書いてみる。まず配列を用意し、そこに行を入れ、最後配列をシャッフルした後に個々の配列要素を出力してみるという、正統派なコードを書いてみる。
a=[]
STDIN.each{|l| a << l.chop}
a.shuffle.each{|x| print x,"\n"}
一行で書くなら次のようになる。
ruby -e 'a=[]; STDIN.each{|l| a << l.chop};a.shuffle.each{|x| print x,"\n"}'
もうちょっと短くできないか考えてみる。まること読み込んで、最後の改行で分割して配列にし、それに対しシャッフルする。
ruby -e ' STDIN.read.split("\n").shuffle.each{|x| print x,"\n"}'
これrubyで行で読み込んで配列で返すような書き方があってもよさそうな気もするし、eachを使わなくても配列の個々の要素をプリントしてくれる書き方があってもよさそうな気がするが、ちょっと見当たらなかった。
尚、これは最初にbar.txtというファイルが既にあるとして話を進めているが、入力から重複するものをまとめユニーク行のみとし、さらにシャッフルした行を出力する時は、shuffleの前にsort.uniqを入れる。式は次のようになる。
ruby -e 'STDIN.read.split("\n").sort.uniq.shuffle.each{|x| print x,"\n"}'
とりあえず書いてみた。