【问题标题】:Filling/Populating a multidimensional array,, with elements of another array, and adding/incrementing values?用另一个数组的元素填充/填充多维数组,并添加/递增值?
【发布时间】:2014-11-21 14:57:12
【问题描述】:

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 中,我可以轻松添加矩阵/2Darray。

如何在 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]]]

【问题讨论】:

  • 我想这就是你想要的。 choices[ii][jj][kk] = data[kk]
  • @Santosh,谢谢,但由于某种原因,“data[kk]”似乎被添加到了我没想到的地方......
  • aa=Array.new(3,Array.new(2,Array.new(3,Array.new(2,0)))) => [[[[0, 0], [0, 0], [0, 0]], [[0, 0], [0, 0], [0, 0]]], [[[0, 0], [0, 0], [0 , 0]], [[0, 0], [0, 0], [0, 0]]], [[[0, 0], [0, 0], [0, 0]], [[0 , 0], [0, 0], [0, 0]]]] irb(main):027:0> aa[1][1]=bb[0] => [4, 4] irb(main) :028:0> aa => [[[[0, 0], [0, 0], [0, 0]], [4, 4]], [[[0, 0], [0, 0] , [0, 0]], [4, 4]], [[[0, 0], [0, 0], [0, 0]], [4, 4]]]
  • 给我们一个小数据集示例,以及您的预期输出,以及您为解决此问题而编写的代码示例。
  • @theTinMan,添加了一个示例。你能解释一下吗?

标签: ruby arrays multidimensional-array indexing


【解决方案1】:

我更仔细地阅读了documentation on Array

还可以通过显式调用 ::new 来创建数组,该函数带有零、一个(数组的初始大小)或两个参数(初始大小和一个默认对象)。

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

请注意,第二个参数使用对同一对象的引用填充数组。因此,仅在需要使用原生不可变对象(例如符号、数字、真或假)实例化数组的情况下才建议使用。

要创建一个包含单独对象的数组,可以改为传递一个块。此方法可以安全地用于可变对象,例如哈希、字符串或其他数组:

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

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

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

这意味着我正在修改在多个位置引用的元素。而且我必须沿我添加的新维度为每个条目显式创建一个新的 Array 对象,因此以一种增量方式构建额外维度。似乎有多种方法可以做到这一点。一种是块发给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]]

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多