先日、会社のチャットワークでそういう話題が出て、いろんな方法があることを知った。
1. array.count(item)
l = [1,2,2,1,3] l.uniq.map{|item| [item, l.count(item)]}.to_h
配列の変数のcountメソッドの引数に値を渡したら同じ値をカウントしてくれるっていうのは知らなかった。
2. array.group_by(&:itself)を使ってからmap
l = [1,2,2,1,3] l.group_by(&:itself).map{ |k, v| [k, v.size] }.to_h
group_by
をしているほうがイケてる感じ。しかしto_h
がなんかダサい…。これをなんとかしたい…。
3. array.group_by後にtransform_values
l = [1,2,2,1,3] l.group_by(&:itself).transform_values(&:size)
うおお、あったー!transform_values
メソッド!Hashのvalueを更新するメソッド。
メソッド名はちと長いけれど、これが一番イケてる。ブロック書かずに済んだし。
itself
メソッドも知らなかったので収穫であった。
こういう話題が社内で流れてくると楽しいですね。
追記(2022-04-22)
Ruby 2.7でEnumerable#tally
メソッドが追加されています。これを使うと同じことができます。めちゃくちゃ短くてシンプル!
l = [1,2,2,1,3] l.tally # => {1 => 2, 2 => 2, 3 => 1}