Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Arrays ruby中深度嵌套数组的重载[]=_Arrays_Ruby - Fatal编程技术网

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创建一个长度等于边界乘积的数组,然后通过正确重载
[]
[]=
来模拟多维数组。这似乎也可以解决我当前的引用问题。