我想初始化一个三维ruby数组。对于二维数组,我可以做
a = Array.new(4){ Array.new(5, 0) }
所以我试过了
a = Array.new(4) { Array.new(5, Array.new(6, 0)) }
但如果我a[1][2][3] = 5
,它不仅将该元素设置为5
,而且将相应的元素设置为其他子数组中的5
,即
[[[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, 5, 0, 0], [0, 0, 0, 5, 0, 0], [0, 0, 0, 5, 0, 0], [0, 0, 0, 5, 0, 0], [0, 0, 0, 5, 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, 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 :(得分:4)
问题在于,如果将值作为参数传递,您将获得一个数组,其中每个值都引用同一个对象。你可以这样做:
Array.new(5, Array.new(6, 0))
您可以使用Array#*
,即数组乘法:
[[[0] * 6] * 5] * 4
答案 1 :(得分:1)
对所有维度使用相同的语法(使用块而不是参数:Array.new(n){...}
)。
a = Array.new(4) { Array.new(5) { Array.new(6, 0) } }
这样,您的代码将创建20个区别Array.new(6, 0)
子子数组,而不是复制相同的对象5次。
require 'pp'
a = Array.new(4) { Array.new(5) { Array.new(6, 0) } }
a[1][2][3] = 5
pp a
# [[[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, 0, 0, 0, 0, 0],
# [0, 0, 0, 5, 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, 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]]]
答案 2 :(得分:0)
以下工作正常。
a=Array.new(4){ Array.new(5) { Array.new(6,0) }}
答案 3 :(得分:0)
您可以使用递归来初始化任何维度的多维数组的元素。 1
<强>代码强>
def init(n, *rest)
rest.empty? ? Array.new(n, 0) : Array.new(n) { init(*rest) }
end
<强>实施例强>
dims = [2, 3, 2]
a = init(*dims)
#=> [[[0, 0], [0, 0], [0, 0]], [[0, 0], [0, 0], [0, 0]]]
a[0][0][0] = 1
a #=> [[[1, 0], [0, 0], [0, 0]], [[0, 0], [0, 0], [0, 0]]]
dims = [2, 3, 2, 4, 2, 3]
a = init(*dims)
a.flatten.size
#=> 288 (= 2*3*2*4*2*3)
a[0][0][0][0][0][0] = 1
a.flatten.count(1)
#=> 1
<强>解释强>
步骤如下。
假设,如示例中所示,
dims = [2, 3, 2]
然后
n, *rest = dims
#=> [2, 3, 2]
n #=> 2
rest
#=> [3, 2]
作为rest.empty? #=> false
,方法返回
Array.new(2) { init(*[3, 2]) } # (1)
#=> [[[0, 0], [0, 0], [0, 0]], [[0, 0], [0, 0], [0, 0]]]
要获得此结果,我们执行块
{ init(*[3, 2]) }
对于正在构造的数组的两个元素中的每一个。这需要我们计算init([3, 2])
(与{ init(3, 2) }
相同),其操作如下。
n, *rest = [3, 2]
#=> [3, 2]
n #=> 3
rest
#=> [2]
再次,作为rest.empty? #=> false
,我们返回
Array.new(3) { init(*[2]) } # (2)
#=> [[0, 0], [0, 0], [0, 0]]
至上述表达式(1)。对于该数组的3个元素中的每一个,我们执行块
{ init(*[2]) }
这要求我们计算init([2])
,其操作如下。
n, *rest = [2]
#=> [2]
n #=> 2
rest
#=> []
这次,自rest.empty? #=> true
起,我们计算并返回
Array.new(2, 0)
#=> [0, 0]
到上面的表达式(2)。
1是的,没有&#34;多维数组&#34;在Ruby中,但我希望读者知道我的意思。替代方法类似于#34; ...包含大小相等的嵌套数组,包含任意数量的嵌套级别&#34;,但即使这样也不完整,因为它无法排除,例如,{{1} }。如果Ruby有这样的对象的名称,将会很有帮助。