Tambourine作業メモ

主にスキル習得のためにやった作業のメモ。他人には基本的に無用のものです。

Ruby版 sort |uniq -c

[ruby-list:45572](http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-list/45572)は、awk

/t$ cat A
yahoo
goo
google
yahoo
msn
msn
/t$ awk '{ class[$1]++ } END { for (i in class){print i, class[i]}}' A
google 1
msn 2
goo 1
yahoo 2

の様にやるようなワンライナをRubyでやる話題

何も意識せずに普通に書いたらこう。

/t$ cat hoge.rb
#!/usr/bin/env ruby

h = Hash.new(0)

while line = gets
  h[line.chomp] +=1
end

h.to_a.sort{|a,b| a[0] <=> b[0]}.each do |i|
  puts "\t#{i[1]} #{i[0]}"
end
/t$ hoge.rb A
        1 goo
        1 google
        2 msn
        2 yahoo

るびきちさんのawkの直訳版

/t$ ruby -lne '(h||=Hash.new(0))[$_]+=1;END{for k,v in h do print k," ",v end}' A
yahoo 2
google 1
goo 1
msn 2

石塚さんの回答は、

/t$ ruby -e "puts ARGF.group_by{|w| w}.map{|key, ary| [key.chomp, ary.size].join(' ')}" A
google 1
msn 2
goo 1
yahoo 2

・・・irbで追っかけてみる

/t$ irb
>> lines = File.readlines("A")
=> ["yahoo\r\n", "goo\r\n", "google\r\n", "yahoo\r\n", "msn\r\n", "msn\r\n"]
>> lines.group_by{|w| w}
=> {"google\r\n"=>["google\r\n"], "msn\r\n"=>["msn\r\n", "msn\r\n"], "goo\r\n"=>
["goo\r\n"], "yahoo\r\n"=>["yahoo\r\n", "yahoo\r\n"]}
>> lines.group_by{|w| w}.map{|key, ary| [key.chomp, ary.size]}
=> [["google", 1], ["msn", 2], ["goo", 1], ["yahoo", 2]]
>> lines.group_by{|w| w}.map{|key, ary| [key.chomp, ary.size].join(" ")}
=> ["google 1", "msn 2", "goo 1", "yahoo 2"]
>> puts lines.group_by{|w| w}.map{|key, ary| [key.chomp, ary.size].join(" ")}
google 1
msn 2
goo 1
yahoo 2
=> nil

なるほど。