【问题标题】:How to concatenate values inside two arrays in Ruby如何在Ruby中连接两个数组内的值
【发布时间】:2016-10-06 18:30:52
【问题描述】:

假设我有以下两个数组:

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

我想创建(或修改 a 或 b)一个数组,其中 values 在要添加在一起的数组的每个相对索引内,例如:

[1, 5, 7, 7, 7]

是否有一种优雅(且快速)的方法可以做到这一点无需循环第一个数组中的每个索引并从第二个数组中添加。我觉得 map/reduce/inject 可能是一种方法,但这些方法对我来说总是有点“神奇”,我从来没有真正理解它们。

【问题讨论】:

    标签: arrays ruby


    【解决方案1】:

    你可以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]
    

    【讨论】:

    • 对于固定数量的参数,我会使用a.zip(b).map { |i, j| i + j } 而不是reduce
    【解决方案2】:

    这是你可以做的事情之一。

    [[4,5,6], [10,25,16]].transpose.map {|x| x.reduce(:+)}
    

    即使inject 也会这样做。

    [[10,20,30],[24,52,62]].transpose.map {|a| a.inject(:+)}
    

    并有更多的了解。请看ruby: sum corresponding members of two or more arrays

    【讨论】:

      【解决方案3】:
      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 是最快的:flamine is faster than surya_2 by 10.000000000000009% ± 10.0%。需要注意的是,flamine 的技术将 b 修改为一个空数组。

        【讨论】:

          【解决方案5】:

          我喜欢这个变体,但它只有在 a.size >= b.size 时才能正常工作

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

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2010-09-09
            • 2010-12-14
            • 2020-02-24
            • 2020-02-05
            • 1970-01-01
            相关资源
            最近更新 更多