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



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

这意味着如果有两个数组:

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

结果应该是:

=> [3, 5, 11]

假设两个数组的大小相同。

我使用的代码感觉不像是完成该任务的 Ruby 方式:

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

这应该有效:

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

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

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

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

基准

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

输出

                 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)
a.zip(b).map(&:max) # => [3, 5, 11]

下面怎么样?

注意:两个数组的大小应相等。

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

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]

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]

基准

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

输出

    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)

最新更新