如何获取两个数组之间的最大值数组

时间:2022-07-16 21:29:37

I'm looking for an elegant way of getting an array containing the maximum values between two arrays.

我正在寻找一种优雅的方法来获取包含两个数组之间的最大值的数组。

Meaning if there are two arrays:

意思是有两个数组:

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

The result should be:

结果应该是:

=> [3, 5, 11]

Assume both arrays are of the same size.

假设两个阵列的大小相同。

The code I use doesn't feel like a Ruby way to do that task:

我使用的代码不像Ruby那样做任务:

c = Array.new(a.size)
for i in 0...a.size
  c[i] = [a[i], b[i]].max
end

3 个解决方案

#1


14  

This should work:

这应该工作:

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

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

转置返回[[1,3],[5,2],[9,11]]和map(&:max)查找每个子数组的最大值。

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

a.zip(b)(如Abe Voelker所建议的)相当于[a,b] .transpose如果两个数组具有相同数量的元素。如果元素大小不同,转置将引发异常:

[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)

#2


7  

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

#3


4  

How is the below ?

下面怎么样?

Note: Size should be equal of both 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)

#1


14  

This should work:

这应该工作:

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

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

转置返回[[1,3],[5,2],[9,11]]和map(&:max)查找每个子数组的最大值。

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

a.zip(b)(如Abe Voelker所建议的)相当于[a,b] .transpose如果两个数组具有相同数量的元素。如果元素大小不同,转置将引发异常:

[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)

#2


7  

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

#3


4  

How is the below ?

下面怎么样?

Note: Size should be equal of both 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)