Ruby_Array_44

この記事は、以下のドキュメントを改変(自分なりに整理)して利用しています。

class Array (Ruby 3.1 リファレンスマニュアル)

インスタンスメソッド

product(*lists) -> Array
product(*lists) { |e| ... } -> self
  • レシーバの配列と引数で与えられた配列のそれぞれから要素を1個ずつとって配列とし、それらのすべての配列を要素とする配列を返す。つまり、返される配列の長さはレシーバと引数で与えられた配列の長さの積になる
    • 引数の配列は複数指定可能
  • ブロックが与えられた場合、作成した配列の各要素を引数としてブロックを実行してselfを返す
    • どういうときに使うのだろうか?
irb(main):001:0> arr = %w[a b c]
=> ["a", "b", "c"]

irb(main):002:0> brr =arr.product([1, 2])
=> [["a", 1], ["a", 2], ["b", 1], ["b", 2], ["c", 1], ["c", 2]]

irb(main):003:0> arr[0].upcase!
=> "A"

irb(main):004:0> arr
=> ["A", "b", "c"]

irb(main):005:0> brr
=> [["A", 1], ["A", 2], ["b", 1], ["b", 2], ["c", 1], ["c", 2]]

# memo
# selfに破壊的変更を加えると影響が出る
irb(main):001:0> [1, 2, 3].product(['a', 'c'], ['X', 'Y', 'Z'])
=> [[1, "a", "X"], [1, "a", "Y"], [1, "a", "Z"], [1, "c", "X"], [1, "c", "Y"], [1, "c", "Z"], [2, "a", "X"], [2, "a", "Y"], [2, "a", "Z"], [2, "c", "X"], [2, "c", "Y"], [2, "c", "Z"], [3, "a", "X"], [3, "a", "Y"], [3, "a", "Z"], [3, "c", "X"], [3, "c", "Y"], [3, "c", "Z"]]
irb(main):001:0> [1, 2, 3].product
=> [[1], [2], [3]]

irb(main):003:0> [1, 2, 3].product([])
=> []

# memo
# これは覚えておきたい
irb(main):001:0> arr = %w[a b c]
=> ["a", "b", "c"]

irb(main):002:0> brr = []
=> []

irb(main):003:0> arr.product([1, 2]) { |elem| brr << elem }
=> ["a", "b", "c"]

irb(main):004:0> brr
=> [["a", 1], ["a", 2], ["b", 1], ["b", 2], ["c", 1], ["c", 2]]

irb(main):005:0> arr[0].upcase!
=> "A"

irb(main):006:0> arr
=> ["A", "b", "c"]

irb(main):007:0> brr
=> [["A", 1], ["A", 2], ["b", 1], ["b", 2], ["c", 1], ["c", 2]]
arr = [1, 2, 3]
brr = [7, 8]

# 例1
sum = 0
arr.each do |i|
  brr.each do |j|
    sum += i * j
  end
end

# 例2
arr
  .product(brr)
  .inject(0) { |result, item| result + item[0] * item[1] }

# memo
# こういう感じで書けるのか
# Rubyに詳しくない人にとっては例1のほうが可読性高そう・・・

メモ