Techioz Blog

Ruby配列内の同一の文字列要素を数える方法

概要

次の配列があります = [“Jason”, “Jason”, “Teresa”, “Judah”, “Michelle”, “Judah”, “Judah”, “Allison”]

同一の要素ごとにカウントを生成するにはどうすればよいですか?

Where:
"Jason" = 2, "Judah" = 3, "Allison" = 1, "Teresa" = 1, "Michelle" = 1?

またはハッシュを生成します。

どこ: ハッシュ = { “ジェイソン” => 2、“ジュダ” => 3、“アリソン” => 1、“テレサ” => 1、“ミシェル” => 1 }

解決策

Ruby v2.7.0 (2019 年 12 月リリース) の時点で、コア言語には Enumerable#tally (この問題専用に設計された新しいメソッド) が含まれるようになりました。

names = ["Jason", "Jason", "Teresa", "Judah", "Michelle", "Judah", "Judah", "Allison"]

names.tally
#=> {"Jason"=>2, "Teresa"=>1, "Judah"=>3, "Michelle"=>1, "Allison"=>1}

次のコードは、この質問が最初に質問されたとき (2011 年 2 月)、標準 Ruby では使用できませんでした。

Ruby へのこれらの最新の追加により、次の実装が可能になります。

names = ["Jason", "Jason", "Teresa", "Judah", "Michelle", "Judah", "Judah", "Allison"]

names.group_by(&:itself).transform_values(&:count)
#=> {"Jason"=>2, "Teresa"=>1, "Judah"=>3, "Michelle"=>1, "Allison"=>1}

さらに古い Ruby バージョンの場合は、上記の Hash#transform_values メソッドにアクセスせずに、代わりに Ruby v2.1.0 (2013 年 12 月リリース) に追加された Array#to_h を使用できます。

names.group_by(&:itself).map { |k,v| [k, v.length] }.to_h
#=> {"Jason"=>2, "Teresa"=>1, "Judah"=>3, "Michelle"=>1, "Allison"=>1}

Ruby のさらに古いバージョン (<= 2.1) の場合、これを解決する方法はいくつかありますが、(私の意見では) 明確な「最善の」方法はありません。この投稿に対する他の回答を参照してください。