Reputation: 43
In Ruby, how can one multiply every element in one array by every element in another array, such that:
a = [1,2,3]
b = [4,5,6]
c = a*b = [4,5,6,8,10,12,12,15,18]
Upvotes: 4
Views: 525
Reputation: 110675
This solution makes use of Matrix methods to compute (and then flatten) the outer product of two vectors.
require 'matrix'
(Matrix.column_vector(a) * Matrix.row_vector(b)).to_a.flatten
#=> [4, 5, 6, 8, 10, 12, 12, 15, 18]
Like the other two answers to date, this produces a temporary array, which when flattened (if not already flattened) contains a.size**2
elements. If a
is so large that this results in a storage problem, you could use a pair of enumerators instead:
a.each_with_object([]) { |aa,arr| b.each { |bb| arr << aa*bb } }
#=> [4, 5, 6, 8, 10, 12, 12, 15, 18]
The enumerators are as follows.
enum_a = a.each_with_object([])
#=> #<Enumerator: [1, 2, 3]:each_with_object([])>
aa, arr = enum_a.next
#=> [1, []]
aa, arr = enum_a.next
#=> [2, []]
...
enum_b = b.each
#=> #<Enumerator: [4, 5, 6]:each>
bb = enum_b.next
#=> 4
bb = enum_b.next
#=> 5
...
See Enumerator#next. This is how enumerators pass elements to their blocks.
The method Enumerable#each_with_object is very convenient and not as complex as it may initially seem. For the most part it just saves two lines of code from the following.
arr = []
a.each { |aa| b.each { |bb| arr << aa*bb } }
arr
Upvotes: 5
Reputation: 5552
Tried with following,
a.product(b).map { |x| x.inject(&:*) }
Amazingly following also solve it,
a.map { |x| b.map(&x.method(:*)) }.flatten
Upvotes: 2
Reputation: 198324
For a nice abstraction, can get cartesian product using product
:
a.product(b).map { |aa, bb| aa * bb }
Upvotes: 10
Reputation: 2409
This is not beautiful but returns what you want.
a.map{|aa| b.map{|bb| bb * aa}}.flatten
Upvotes: -3