How to get an array of maximum values ​​between two arrays

I am looking for an elegant way to get an array containing the maximum values ​​between two arrays.

Value if there are two arrays:

a = [1, 5, 9] b = [3, 2, 11] 

The result should be:

 => [3, 5, 11] 

Suppose both arrays are the same size.

The code I use is not like Ruby's way to accomplish this task:

 c = Array.new(a.size) for i in 0...a.size c[i] = [a[i], b[i]].max end 
+6
source share
3 answers

This should work:

 [a, b].transpose.map(&:max) #=> [3, 5, 11] 

transpose returns [[1, 3], [5, 2], [9, 11]] and map(&:max) finds the maximum maximum of each array.

a.zip(b) (as suggested by Abe Voelker) is equivalent to [a, b].transpose if both arrays have the same number of elements. If the element size is different, transpose will throw an exception:

 [1].zip([2,3]) #=> [[1,2]] [[1], [2,3]].transpose #=> IndexError: element size differs 

Benchmarks

 require 'benchmark' a = (1..1000).to_a b = a.reverse n = 1000 Benchmark.bm(10) do |x| x.report("transpose") { n.times { [a,b].transpose.map(&:max) } } x.report("zip") { n.times { a.zip(b).map(&:max) } } x.report("lazy.zip") { n.times { a.lazy.zip(b).map(&:max).to_a } } x.report("loop (max)") { n.times { a.size.times.map{|i| [a[i],b[i]].max} } } x.report("loop (>?:)") { n.times { a.size.times.map{|i| a[i]>b[i] ? a[i] : b[i] } } } end 

Output

  user system total real transpose 0.430000 0.000000 0.430000 ( 0.428760) zip 0.420000 0.000000 0.420000 ( 0.415070) lazy.zip 1.010000 0.000000 1.010000 ( 1.009173) loop (max) 0.490000 0.000000 0.490000 ( 0.489015) loop (>?:) 0.150000 0.000000 0.150000 ( 0.151461) 
+14
source
 a.zip(b).map(&:max) # => [3, 5, 11] 
+7
source

How below?

Note. The size should be equal as for the array.

 a = [1, 5, 9] b = [3, 2, 11] p a.size.times.map{|i| [a[i],b[i]].max} # >> [3, 5, 11] 

or

 a = [1, 5, 9] b = [3, 2,11] p a.size.times.map{|i| a[i]>b[i] ? a[i] : b[i] } # >> [3, 5, 11] 

Or

 a = [1, 5, 9] b = [3, 2, 11] p a.each_index.map{|i| a[i]>b[i] ? a[i] : b[i] } # >> [3, 5, 11] 

Benchmark

 require 'benchmark' iterations = 10_000 a = [1, 5, 9] b = [3, 2,11] def stefan(a,b) [a, b].transpose.map(&:max) end def abe(a,b) a.zip(b).map(&:max) end def babai1(a,b) a.size.times.map{|i| a[i]>b[i] ? a[i] : b[i] } end def babai2(a,b) a.size.times.map{|i| [a[i],b[i]].max} end def babai3(a,b) a.each_index.map{|i| a[i]>b[i] ? a[i] : b[i] } end Benchmark.bm do |bm| bm.report('Stefan') do iterations.times do stefan(a,b) end end bm.report('Abe') do iterations.times do abe(a,b) end end bm.report('babai1') do iterations.times do babai1(a,b) end end bm.report('babai2') do iterations.times do babai2(a,b) end end bm.report('babai3') do iterations.times do babai3(a,b) end end end 

output

  user system total real Stefan 0.047000 0.000000 0.047000 ( 0.046874) Abe 0.047000 0.000000 0.047000 ( 0.046873) babai1 0.031000 0.000000 0.031000 ( 0.031249) babai2 0.062000 0.000000 0.062000 ( 0.062497) babai3 0.032000 0.000000 0.032000 ( 0.031249) 
+4
source

Source: https://habr.com/ru/post/953636/


All Articles