言語
日本語
English

Caution

お使いのブラウザはJavaScriptが無効になっております。
当サイトでは検索などの処理にJavaScriptを使用しています。
より快適にご利用頂くため、JavaScriptを有効にしたうえで当サイトを閲覧することをお勧めいたします。

Ruby辞典

  1. トップページ
  2. Ruby辞典
  3. Enumerable.flat_map / group_by / tally

Enumerable.flat_map / group_by / tally

対応: Ruby 2.7(2019)

コレクションの平坦化・グルーピング・集計を行うメソッドです。データの集約処理に役立ちます。

構文

# mapの結果を1段階平坦化します。
コレクション.flat_map { |要素| 変換式 }

# ブロックの戻り値をキーにしてグループ分けします。
コレクション.group_by { |要素| キー }

# 要素の出現回数を集計したハッシュを返します。
コレクション.tally

# ネストした配列を平坦にします。
配列.flatten
配列.flatten(深さ)

メソッド一覧

メソッド概要
flat_map各要素にブロックを適用し、結果の配列を1段階平坦化して返します。
group_byブロックの戻り値をキー、一致する要素の配列を値とするハッシュを返します。
tally各要素の出現回数を集計し、『{要素 => 回数}』のハッシュを返します。
flattenネストした配列を再帰的に平坦化します。引数で深さを制限できます。

サンプルコード

sample_enumerable_flat_map_group_by_tally.rb
# flat_map でネストした配列を平坦化しながら変換します。
sentences = ["Iori Yagami", "Terry Bogard"]
word_list = sentences.flat_map { |s| s.split(" ") }
puts word_list.inspect  # ["Iori", "Yagami", "Terry", "Bogard"]

# group_by で所属チームごとにグループ分けします。
fighters = [
  { name: "八神庵", team: "八神チーム" },
  { name: "草薙京", team: "草薙チーム" },
  { name: "テリー・ボガード", team: "餓狼チーム" },
  { name: "ブルー・マリー", team: "餓狼チーム" }
]
by_team = fighters.group_by { |f| f[:team] }
puts by_team["八神チーム"].map { |f| f[:name] }.inspect   # ["八神庵"]
puts by_team["餓狼チーム"].map { |f| f[:name] }.inspect   # ["テリー・ボガード", "ブルー・マリー"]

# tally で出現回数を集計します。
teams = ["八神チーム", "草薙チーム", "八神チーム", "餓狼チーム", "草薙チーム", "八神チーム"]
tally = teams.tally
puts tally.inspect  # {"八神チーム"=>3, "草薙チーム"=>2, "餓狼チーム"=>1}

# 最も多い要素を取得します。
most_common = tally.max_by { |_, count| count }
puts "最多: #{most_common[0]}(#{most_common[1]}回)"  # 最多: 八神チーム(3回)
ruby enumerable_flat_map_group_by_tally.rb
["Iori", "Yagami", "Terry", "Bogard"]
["八神庵"]
["テリー・ボガード", "ブルー・マリー"]
{"八神チーム"=>3, "草薙チーム"=>2, "餓狼チーム"=>1}
最多: 八神チーム(3回)

概要

『flat_map』は『map』と『flatten(1)』を組み合わせた操作を1回で行います。各要素から配列を生成してそれをまとめたい場合に便利です。『group_by』はデータを分類するときに活用でき、戻り値はハッシュです。

『tally』はRuby 2.7で追加されたメソッドで、要素の出現回数を手軽に集計できます。それ以前のバージョンでは『each_with_object』や『inject』で同等の処理を実装する必要がありました。ログ解析や投票集計など、頻度カウントが必要な場面で重宝します。

記事の間違いや著作権の侵害等ございましたらお手数ですがまでご連絡頂ければ幸いです。