KGSoloman
KGSoloman

Reputation: 43

Multiply each item in an array by each item in another array

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

Answers (4)

Cary Swoveland
Cary Swoveland

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

ray
ray

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

Amadan
Amadan

Reputation: 198324

For a nice abstraction, can get cartesian product using product:

a.product(b).map { |aa, bb| aa * bb }

Upvotes: 10

shirakia
shirakia

Reputation: 2409

This is not beautiful but returns what you want.

a.map{|aa| b.map{|bb| bb * aa}}.flatten

Upvotes: -3

Related Questions