使用另一个数组的元素填充/填充多维数组,以及添加/递增值?

时间:2014-11-21 14:57:13

标签: ruby arrays multidimensional-array indexing

Ruby我有一个多维数组,4D;

choices[ii][jj][kk][ll].

我有另一个阵列;

data[kk][ll]
choices[ii][jj].size==data.size
choices[ii][jj][kk].size==data[kk].size

我想用数据元素填充选项的最后两个维度,因为它们的大小相同,我正在寻找一种需要很少代码的方法。

在MATLAB中,我知道如何使用下标索引轻松完成这项工作;例如。 choices[ii,jj,:,:]=data[:,:]。同样,在MATLAB中我可以轻松添加矩阵/ 2D阵列。

如何在Ruby中完成?

编辑:示例

bb=Array.new(2,4)
aa=Array.new(3,Array.new(2,0))
=> [[0, 0], [0, 0], [0, 0]]
irb(main):006:0> aa[1]=bb
 => [4, 4]
irb(main):007:0> aa
=> [[0, 0], [4, 4], [0, 0]]

这没关系,但对于3D数组,我将数组'bb'复制到我不想要的部分:

aa=Array.new(3,Array.new(2,Array.new(2,0)))
=> [[[0, 0], [0, 0]], [[0, 0], [0, 0]], [[0, 0], [0, 0]]]
irb(main):013:0> aa[2][1]=bb
=> [4, 4]
irb(main):014:0> aa
=> [[[0, 0], [4, 4]], [[0, 0], [4, 4]], [[0, 0], [4, 4]]]

1 个答案:

答案 0 :(得分:0)

我更仔细地阅读了documentation on Array

也可以通过显式调用:: new with zero,one(Array的初始大小)或两个参数(初始大小和默认对象)来创建数组。

ary = Array.new    #=> []
Array.new(3)       #=> [nil, nil, nil]
Array.new(3, true) #=> [true, true, true]

请注意,第二个参数使用对同一对象的引用填充数组。因此,仅在需要使用本机不可变对象(如符号,数字,true或false)实例化数组时才建议使用它。

要创建具有单独对象的数组,可以传递一个块。此方法可以安全地与可变对象(如哈希,字符串或其他数组)一起使用:

Array.new(4) { Hash.new } #=> [{}, {}, {}, {}]

这也是构建多维数组的快捷方法:

 empty_table = Array.new(3) { Array.new(3) }
 #=> [[nil, nil, nil], [nil, nil, nil], [nil, nil, nil]]

这意味着我正在修改多个地方引用的元素。而且我必须为我添加的新维度为每个条目显式创建一个新的Array对象,因此以增量方式构建额外维度。似乎有多种方法可以做到这一点。一种是发送到Array的块的这种方法,另一种是在维度上执行迭代器并为每个条目创建一个新的数组。

我还发现这个post以非常简单的方式强调了这个问题:>>

错误的方式,我看到人们经常尝试的方式是说Array.new(4,Array.new(4,0))。换句话说,一个4行的数组,每行是4个零的数组。这似乎首先起作用。但是,请运行以下代码:

 a = Array.new( 4, Array.new(4, 0) ) a[0][0] = 1 pp a 

看起来很简单。制作一个4x4的零数组,将左上角的元素设置为1.但是打印它然后我们得到......

[[1, 0, 0, 0], [1, 0, 0, 0], [1, 0, 0, 0], [1, 0, 0, 0]] 

它将整个第一列设置为1,是什么给出的?当我们创建数组时,最先调用Array.new的最内部调用,创建一行。然后对该行的单个引用重复4次以填充最外部的数组。然后每行引用相同的数组。更改一个,全部更改。

我们传递一个块,而不是将值传递给Array.new方法。每次Array.new方法需要新值时,都会执行该块。所以如果你说Array.new(5){gets.chomp},Ruby会停下来并要求输入5次。所以我们需要做的就是在这个块中创建一个新数组。所以我们最终得到了Array.new(4){Array.new(4,0)}。现在让我们再次尝试该测试用例。

 a = Array.new(4) { Array.new(4, 0) } a[0][0] = 1 pp a 

它就像你期望的那样。

 [[1, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]