Reduce / Inject
CoddyのRubyジャーニー「ロジックとフロー」セクションの一部 — レッスン 23/56。
配列全体を、合計や積、あるいは最も長い文字列といった単一の値にまとめたい場合があります。reduce(inject とも呼ばれます。同じメソッドに2つの名前があります)がそのためのツールです。
このブロックは、アキュムレータと現在の要素の2つのパラメータを受け取ります。ブロックの戻り値が次のアキュムレータになります。
total = [1, 2, 3, 4].reduce(0) { |acc, n| acc + n }
puts total # 10ステップバイステップで、アキュムレータは 0 → 1 → 3 → 6 → 10 となります。
第1引数はアキュムレータの初期値です。省略した場合、Rubyは配列の最初の要素を使用します。
[1, 2, 3, 4].reduce { |acc, n| acc * n } # 24合計や積のような純粋な演算の場合、Rubyにはショートカットがあります。ブロックの代わりにシンボルを渡します:
[1, 2, 3, 4].reduce(:+) # 10
[1, 2, 3, 4].reduce(:*) # 24カスタムアキュムレータを構築できるようになれば、ほとんどすべてのことを1回のパスで計算できるようになります。
チャレンジ
簡単カンマ区切りの整数のリストを読み込みます。次の3行を出力してください:
- 合計(
reduce(:+)を使用) - 積(
reduce(:*)を使用) - 最大値(
maxを使用せず、reduceと明示的なブロックを使用して計算)
入力が 2,5,3,8 の場合、出力は以下のようになります:
18
240
8チートシート
reduce (別名: inject) は、配列を単一の値にまとめます。ブロックはアキュムレータと現在の要素を受け取り、その戻り値が次のアキュムレータになります。
total = [1, 2, 3, 4].reduce(0) { |acc, n| acc + n } # 10初期値を省略すると、最初の要素が初期のアキュムレータとして使用されます:
[1, 2, 3, 4].reduce { |acc, n| acc * n } # 24単純な操作のショートカットとしてシンボルを渡すことができます:
[1, 2, 3, 4].reduce(:+) # 10
[1, 2, 3, 4].reduce(:*) # 24自分で試してみよう
numbers = gets.chomp.split(",").map(&:to_i)
# TODO: 合計、積、最大値を出力する(reduceと明示的なブロックを使用)
このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。
ロジックとフローのすべてのレッスン
5Enumerable の強力な機能
Select と RejectMap のメソッドチェーンReduce / Injectcount, all?, any?, none?group_by と partitionsort_by, min_by, max_byまとめ:データパイプライン