同じ年月は同じグループとしてカウントして数を求める例でのコード比較をRubyでも
はじめに
同じ年月は同じグループとしてカウントして数を求める例でのコード比較を Squeak Smalltalk でも - Smalltalkのtは小文字です経由でこんな問題を見つけたのでRubyでやってみました。
各言語共通ロジック条件
- 同じ年月は同じグループとしてカウントして数を求める
- 最新の年月を降順でソートする
- 無理やり1行にまとめず、ある程度の可読性は保つようにする
- 宣言部分、実装メソッドの定義部分などはカウントせず除外する
- //---(logic)----で囲んだ箇所を比較対象箇所とする
- 下記「変更前」データーから「変更後」データになるよう標準出力を行う
変換前 変換後(降順) 件数 2009-11 2010-12 3 2009-01 2010-04 2 2010-01 2010-01 3 2010-12 → 2009-11 1 2010-01 2009-01 1 2010-04 2010-01 2010-12 2010-12 2010-04
コード
コードはこちら。1行だけど可読性は大丈夫なんじゃないかと。
year_months = ['2009-11', '2009-01', '2010-01', '2010-12', '2010-01', '2010-04', '2010-01', '2010-12', '2010-12', '2010-04'] # ------(logic)-------------------- year_months.group_by { |ym| ym }.sort.reverse.each { |k, v| puts "#{k} => #{v.size}" } # ------(logic)--------------------
結果はこんな感じ。
2010-12 => 3
2010-04 => 2
2010-01 => 3
2009-11 => 1
2009-01 => 1
Rubyにもgroup_byってあるのね
Enumerableのインスタンスメソッドだそうです。知りませんでした。
instance method Enumerable#group_by - Ruby 1.9.2 Reference Manual
ブロックを評価した結果をキー、対応する要素の配列を値とするハッシュが返ってきます。
[1, 1, 2, 3].group_by { |x| x } #=> {1=>[1, 1], 2=>[2], 3=>[3]} (1..10).group_by { |x| x % 2 == 0 } #=> {false=>[1, 3, 5, 7, 9], true=>[2, 4, 6, 8, 10]}
まとめ
group_byけっこう便利かもしれない。