Arrays ruby中深度嵌套数组的重载[]=
我正在处理一个类,它使用嵌套任意深度的数组数组。 我想重载Arrays ruby中深度嵌套数组的重载[]=,arrays,ruby,Arrays,Ruby,我正在处理一个类,它使用嵌套任意深度的数组数组。 我想重载[]和[]=方法,以便更轻松地访问嵌套数组的条目。 我已经让[]工作了,但是当我嵌套超过两个级别时,[]=仍然给我带来问题。 这是密码 class Space attr_reader :grid def initialize(*bounds) @dim = bounds.length @bounds = bounds @grid = create_grid end def [](*coords)
[]
和[]=
方法,以便更轻松地访问嵌套数组的条目。
我已经让[]
工作了,但是当我嵌套超过两个级别时,[]=
仍然给我带来问题。
这是密码
class Space
attr_reader :grid
def initialize(*bounds)
@dim = bounds.length
@bounds = bounds
@grid = create_grid
end
def [](*coords)
entry = @grid
coords.each { |coord| entry = entry[coord] }
entry
end
def []=(*args)
row = @grid
args[0..-3].each { |coord| row = row[coord] }
row[args[-2]] = args.last
end
private
def create_grid
sub_grid = nil
@dim.times do |i|
sub_grid = Array.new(@bounds[i]) { sub_grid }
end
sub_grid
end
end
如您所见,我迭代创建了一个嵌套数组,嵌套深度为@dim
。
然后,如果space
是space的一个实例,那么space[I,j,…]==space[I][j]…
和space[I,j,…]=x
应该与space[I][j]…=x
访问元素有效,但赋值无效。
当我跑的时候
space = Space.new(2,2,2)
space[0,0,0] = true
p space.grid
我希望得到
[[[true, nil], [nil, nil]], [[nil, nil], [nil, nil]]]
但是我得到了
[[[true, nil], [true, nil]], [[true, nil], [true, nil]]]
我怀疑问题在于ruby在每个级别上只持有一个对sub_grid
的引用。
我通过将create_grid
更改为
def create_grid
sub_grid = nil
@dim.times do |i|
sub_grid = Array.new(@bounds[i]) do
sub_grid.nil? ? nil : sub_grid.dup
end
end
sub_grid
end
所以现在我的输出是
[[[true, nil], [nil, nil]], [[true, nil], [nil, nil]]]
哪一个更好,但仍然不是我想要的。
有什么方法可以得到我想要的吗?在我看来就像是在声明空间。新的(2,2,2)
比必须通过发送大量维度,然后发送每个维度的大小来重复自己的操作更符合逻辑args.length
是这个修改后的示例中的数字。@tadman谢谢你的建议。我对代码进行了相应的编辑。由于您要创建的数组数量以指数形式递增,并且具有更大的维数或更大的大小,因此您可能希望模拟多维数组。25x25x25数组有650个单独的数组对象,这是一种浪费。在垃圾收集器上,大小为25*25*25
的单数数组要容易得多,您可以将参数映射到这个单数1D数组中的适当插槽。我明白了,所以我将创建一个长度等于边界乘积的单数组,然后通过适当重载[]
和来模拟多维数组[]=
。这似乎也可以解决我当前的引用问题。在我看来,这就像声明空格。新的(2,2,2)
比通过发送多个维度,然后发送每个维度的大小来重复你自己的操作更符合逻辑。args.length
是这个修改后的示例中的数字。@tadman谢谢你的建议。我相应地编辑了代码。因为你创建的数组数量以指数形式增加,维度数量也增加了或者只是更大的尺寸,您可能希望模拟多维数组。25x25x25数组有650个单独的数组对象,这是一种浪费。大小25*25*25
的单个数组在垃圾收集器上容易得多,您可以将参数映射到这个单个1D数组中的相应插槽。我明白了,所以我想ld创建一个长度等于边界乘积的数组,然后通过正确重载[]
和[]=
来模拟多维数组。这似乎也可以解决我当前的引用问题。