8

I have two arrays, for example

a = [3, 2, 1]
b = [1, 2, 3]

I need to multiply them and create a third array c that will be like this

c = [3 * 1, 2 * 2, 1 * 3]

Which method is the best by speed? I need to do this for huge arrays, and time is important.

sawa
  • 165,429
  • 45
  • 277
  • 381
Maxim 666
  • 91
  • 1
  • 3

4 Answers4

20
a.zip(b).map{|x, y| x * y}

This works because zip combines the two arrays into a single array of two element arrays. i.e.:

a = [3, 2, 1]
b = [1, 2, 3]
a.zip(b)
#=> [[3, 1], [2, 2], [1, 3]]

Then you use map to multiply the elements together. This is done by iterating through each two element array and multiplying one element by the other, with map returning the resulting array.

a.zip(b).map{|x, y| x * y}
#=> [3, 4, 3]
Neddy
  • 57
  • 7
sawa
  • 165,429
  • 45
  • 277
  • 381
  • 4
    If your answer included some informative text you wouldn't have to pad it with a bunch of periods. An answer with only code may be the right answer, but it's never a great answer. – Jordan Running Dec 22 '15 at 16:44
4

Try this:

[[3,2,1],[1,2,3]].transpose.map {|a| a.inject(:*)}
Wand Maker
  • 18,476
  • 8
  • 53
  • 87
Akanksha
  • 178
  • 8
  • Welcome to StackOverflow. For future reference, have a look at [How do I format my code blocks](http://meta.stackexchange.com/questions/22186/how-do-i-format-my-code-blocks) – Wand Maker Dec 22 '15 at 14:41
2

You can try this:

a.map.with_index{ |x, i| a[i]*b[i]}
Sergio Tulentsev
  • 226,338
  • 43
  • 373
  • 367
Radix
  • 2,527
  • 1
  • 19
  • 43
  • Is there a way to avoid `x` as it is not used?. For future reference, have a look at [How do I format my code blocks](http://meta.stackexchange.com/questions/22186/how-do-i-format-my-code-blocks) – Wand Maker Dec 22 '15 at 14:43
0

Since you want to multiply two arrays, we have to assume they are of same size.

Hence, below is a simple way to multiply them - it has O(n) time complexity. Other answers are also equally good, you can pick any one

a = [3, 2, 1]
b = [1, 2, 3]

a.size.times.collect { |i| a[i] * b[i] }
#=> [3, 4, 3]

If time is really of the essence, then, you may want to use multiple threads. A sample program demonstrating the concept is shown below. You can build upon it based on your specific needs.

a = [3, 2, 1]
b = [1, 2, 3]

num_cores = 2 # This decides number of threads, ideally equal to number of cores
ary_size = a.size

# We need to collect result of each thread as separate sub-array.
# We will use result array-of-array so that order of result is preserved
results = Array.new(num_cores, [])

# Divide the array indexes into equal parts    
index_splits = (0...ary_size).each_slice(num_cores)

threads = []

# Process each sub-array in a thread of its own
index_splits.each_with_index do |ary, i| 
    threads << Thread.new do
      results[i] = ary.collect {|j| a[j] * b[j] } 
    end
end
threads.each {|t| t.join} 

p results.flatten
#=> [3,4,3]
Wand Maker
  • 18,476
  • 8
  • 53
  • 87