ネットの海の片隅で

技術ネタの放流、あるいは不法投棄。

Rubyで配列の最多要素を求める

やりたいこと

タイトル通りです。 [1,2,2,3,3,3,4,4,5]から最多の要素3を得たいということがあります。最頻値を求めると言っても良いかもしれません。

やはり同じようなことを考えている人がいるようです。

Ruby - 配列内で要素数が最多のものを求める! - mk-mode BLOG

もうちょっとキレイに書けるのでは?

リンク先のコードでも良いのですが、もうちょっとキレイに書けると思います。

# Ruby2.1以前
[1,2,2,3,3,3,4,4,5].group_by{|e| e}.max_by{|_,v| v.size}.first

# Ruby2.2以降
[1,2,2,3,3,3,4,4,5].group_by(&:itself).max_by{|_,v| v.size}.first

最終的には好みなのかもしれませんが、個人的にはこちらのほうがキレイだと思いますし、#max_byを使ったほうが「最多」を求めているという意図を伝えやすいと思います。

簡単な解説

解説というほどのものでもないですが、こんな感じで動いてます。

[1,2,2,3,3,3,4,4,5].group_by{|e| e}
# => {1=>[1], 2=>[2, 2], 3=>[3, 3, 3], 4=>[4, 4], 5=>[5]}

[1,2,2,3,3,3,4,4,5].group_by{|e| e}.max_by{|_,v| v.size}
# => [3, [3, 3, 3]]

[1,2,2,3,3,3,4,4,5].group_by{|e| e}.max_by{|_,v| v.size}.first
# => 3

その他

最多要素が複数ある場合などは考慮していません。 同率1位の要素があった場合にどれを選ぶのかといったルールが必要な場合は諦めてクラスに切り出しましょう。

Enumerable#modeがあれば良いのかな?