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]
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]
For a nice abstraction, can get cartesian product using product:
a.product(b).map { |aa, bb| aa * bb }
Enumerable#map_reduce to be introduced in Ruby core? :)product is chained to an Enumerable method. (I expect the reason is forehead-slapping simple.)a.enum_for(:product, b).zip is even worse – it just returns (a useless) nil when a block is given.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
Matrix method in Ruby? The idea of writing numerically demanding methods such as Matrix#lup_decomposition in Ruby boggles the mind. I had assumed an optimized public-domain matrix library written in C had been used (with Ruby wrappers). That also would have been a lot easier than reinventing the wheel.Tried with following,
a.product(b).map { |x| x.inject(&:*) }
Amazingly following also solve it,
a.map { |x| b.map(&x.method(:*)) }.flatten
(:*) in your first answer and flat_map in your second answer.reduce since it is allowed by this method only, all of a sudden, while using Symbol#to_proc is the common approach used widely among the whole ruby core.This is not beautiful but returns what you want.
a.map{|aa| b.map{|bb| bb * aa}}.flatten