2016-10-05 144 views
2
两个阵列内的值

说我有以下两个数组:如何连接在红宝石

a = [1, 0, 2, 1, 6] 
b = [0, 5, 5, 6, 1] 

我想创建(或修改或b)用的各相对折射率内部的阵列该阵列被一起加入,如:

[1, 5, 7, 7, 7] 

是否有一个优雅(和快)的方式来做到这一点而不索引循环遍历所述第一阵列中的和从第二加法。我有一种感觉,map/reduce/inject可能是一种去往这里的方式,但这些方法对我来说总是显得有点“神奇”,我从来没有真正理解它们。

回答

6

你可以zip然后用reduce

p a.zip(b).map{|v| v.reduce(:+) } 
#=> [1, 5, 7, 7, 7] 

或者,如果你确定阵列ab将永远是相同的长度:

p a.map.with_index { |v, i| v + b[i] } 
#=> [1, 5, 7, 7, 7] 
+1

对于一个固定数目的参数我会使用'a.zip(B).MAP {|我,j |我+ j}'而不是'reduce'。 – Stefan

4
a.each_index.map { |i| a[i]+b[i] } 
    # => [1, 5, 7, 7, 7] 
4

所有基地似乎都被其他答案所覆盖。这些都必须送交唯一的兴趣:

c = b.cycle 
#=> #<Enumerator: [0, 5, 5, 6, 1]:cycle> 
a.map { |e| e + c.next }               
#=> [1, 5, 7, 7, 7] 

而另一种方式:

a.map { |e| e + b.rotate!.last } 
#=> [1, 5, 7, 7, 7] 

基准

基准(这我并没有被显示在做自己任何好处)较大阵列。

require 'fruity' 

a = (1..10_000).to_a.shuffle 
b = a.shuffle 

compare do 
    sagar  { ar = a.dup; br = b.dup; c = br.cycle; ar.map { |e| e + c.next } } 
    sagar_2 { ar = a.dup; br = b.dup; ar.map { |e| e + br.rotate!.last } } 
    cary  { ar = a.dup; br = b.dup; ar.each_index.map { |i| ar[i]+br[i] } } 
    surya  { ar = a.dup; br = b.dup; ar.zip(br).map{|v| v.reduce(:+) } } 
    surya_2 { ar = a.dup; br = b.dup; ar.map.with_index { |v, i| v + br[i] } } 
    sinsuren { ar = a.dup; br = b.dup; [ar, br].transpose.map {|x| x.reduce(:+)} } 
    flamine { ar = a.dup; br = b.dup; ar.map{|i| br.shift.to_i + i }} 
    stefan { ar = a.dup; br = b.dup; ar.zip(br).map { |i, j| i + j }} 
end 

#Running each test once. Test will take about 3 seconds. 
#flamine is similar to surya_2 
#surya_2 is similar to stefan 
#stefan is similar to cary 
#cary is faster than sinsuren by 3x ± 1.0 
#sinsuren is similar to surya 
#surya is faster than sagar by 2x ± 0.1 
#sagar is faster than sagar_2 by 15x ± 1.0 

跑了几次,有时候眩晕是最快的:flamine is faster than surya_2 by 10.000000000000009% ± 10.0%。需要注意的是Flamine的技巧将b修改为空阵列。

1

我喜欢这个变型中,但是它的正常工作仅当a.size> = b.size

a.map{|i| b.shift.to_i + i }