リスト中に登場する回数の多い要素トップ N を計算するとき、どんな風に書きますか?
順序統計量の話がしたいわけではなく、そういうコードは頻繁に書くわりに、書き方に納得できなくていつも悩んでいるのです。短く、かつ、わかりやすい書き方がポイント高いです (効率は軽視) 。普段は以下のように書いているけど、これは長すぎかつ難解で納得できてません。
ary = %w(foo bar foo baz foo bar qux foo bar qux quux) n = 3 # 回数をカウントする count = Hash.new { 0 } ary.each {|x| count[x] += 1 } # (文字列 -> 回数) のハッシュを反転して (回数 -> [文字列]) にする rev_count = {} count.each {|k, v| (rev_count[v] ||= []) << k } i = 1 # 回数の大きい順に回す rev_count.keys.sort.reverse.each do |v| # 順位を数えながら出力する puts "#{ i } 位:" rev_count[v].each {|k| puts "- #{ k }" } i += rev_count[v].size break if i > n end
ここで悩むのは Hash クラスに何かメソッドが足りてないサインではないか (自分中心的な発想) 。