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のほうが可読性高そう・・・
メモ
- pryを使ってソースコードを見てみるとすごく長かった