【问题标题】:Ruby: unexpected results for multidimensional array initialization [duplicate]Ruby:多维数组初始化的意外结果
【发布时间】:2011-09-24 18:36:51
【问题描述】:

我知道这可能不是好的 Ruby 风格,但我正在学习……这是怎么回事?具体来说,当我认为我正在将数组参数 testa 的值初始化(复制)到 @test 中时,为什么我的数组的第一行是第二行的副本,保持所有索引相同?

class Test
    def initialize (size, testa)
        @test = Array.new(size, Array.new(size));
        (1..size).each { |r|
            (1..size).each { |c|
                @test[r-1][c-1] = testa[r-1][c-1];
                puts("#{r}, #{c}: #{@test[r-1][c-1]}");
            }
        }
    end
end

t= Test.new(2,[[1,2],[3,4]])    #=> @test=[[3, 4], [3, 4]]

【问题讨论】:

    标签: ruby arrays multidimensional-array


    【解决方案1】:

    您看到的问题的原因是您如何初始化数组。您在方法调用中传递了一个新初始化的数组,该数组用作每一行的值。

    # Your initialization
    @test = Array.new(size, Array.new(size));
    
    # The following is equivalent, and perhaps more illustrative of what's happening
    @a    = Array.new(size)
    @test = Array.new(size, @a) # effective result => [@a, @a, @a, @a, @a] 
    

    因此,在您的方法中,当您遍历行时,您会反复更改同一个数组的值。

    要修复它,请为每一行创建一个新数组,而不是 1 个被引用 5 次的数组。这可以使用Array 的块初始化变量来完成。比如:

    @test = Array.new(size) { Array.new(size) }
    

    查看the docs,了解有关数组初始化的不同方法的更多说明。

    【讨论】:

      【解决方案2】:

      参见:http://www.ruby-doc.org/core/classes/Array.html 到 Array.new(size, obj)

      使用 obj 的 size 副本创建(即对同一 obj 的 size 引用)

      对象 'Array.new(size)' 对于每一行都是同一个对象。

      尝试: @test = Array.new(size) { Array.new(size) };

      或您的代码的其他实现:

      class Test
        def initialize(array)
          @test = array.map{|ar| Array.new(ar) }
        end
      end
      t = Test.new([[1,2],[3,4]])
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-08-01
        • 1970-01-01
        • 2013-04-04
        • 2011-04-03
        • 2015-07-20
        相关资源
        最近更新 更多