Menu
Coddy logo textTech

group_by と partition

CoddyのRubyジャーニー「ロジックとフロー」セクションの一部。レッスン 25/56。

コレクションをフィルタリングするのではなく、分割したい場合があります。2つのメソッドでほとんどのケースをカバーできます。

group_by はブロックを受け取り、ハッシュを返します。ブロックの個々のユニークな戻り値がキーとなり、そのキーにはその結果を生成した要素の配列がマッピングされます:

words = ["hi", "hello", "yo", "hey", "bonjour"]
by_length = words.group_by { |w| w.length }
puts by_length.inspect
# {2=>["hi", "yo"], 5=>["hello"], 3=>["hey"], 7=>["bonjour"]}

1回のパスで項目を分類する最もクリーンな方法です。

partition はバイナリバージョンです。ブロックが真であった要素の配列と、それ以外の要素の配列のペアを返します:

evens, odds = [1, 2, 3, 4, 5].partition { |n| n.even? }
puts evens.inspect   # [2, 4]
puts odds.inspect    # [1, 3, 5]

バケットが正確に2つある場合は partition を、多数存在する可能性がある場合は group_by を使用します。

challenge icon

チャレンジ

中級

カンマ区切りの name:score エントリのリスト(例: Alice:88,Bob:42,Charlie:75)を読み込みます。group_by とそれに続く partition を使用して小さなレポートを出力してください。

手順:

  1. 各エントリを [name, score] のペア(score は整数)にパースします
  2. name の最初のエントリの文字(大文字)で group_by します
  3. 各文字のグループについて、アルファベット順に、エントリを合格score >= 60)と不合格partition し、グループごとに1行出力します:
<LETTER>: pass=<names_passing_joined_by_comma> fail=<names_failing_joined_by_comma>

各グループ内では、名前は元の順序で表示されます。一方の側に名前がない場合は、空のままにします(例: fail=)。

入力が Alice:88,Adam:42,Bob:75,Beth:55,Cara:90 の場合、出力は次のようになります:

A: pass=Alice fail=Adam
B: pass=Bob fail=Beth
C: pass=Cara fail=

自分で試してみよう

entries = gets.chomp.split(",").map do |s|
  name, score = s.split(":")
  [name, score.to_i]
end

# TODO: 先頭文字(大文字)でグループ化し、各グループを score >= 60 で分割し、
#       アルファベット順に 'X: pass=... fail=...' を出力
quiz icon腕試し

このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。

ロジックとフローのすべてのレッスン

自分で練習してみよう: Rubyオンラインコンパイラ