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

时间:2013-09-11 14:47:01

标签: ruby

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

表示是否有两个数组:

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

3 个答案:

答案 0 :(得分:14)

这应该有效:

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

答案 1 :(得分:7)

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

答案 2 :(得分:4)

下面怎么样?

注意:大小应该等于数组。

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)