Ruby 2d哈希数组,具有运行时决定的长度

时间:2017-01-13 11:27:13

标签: arrays ruby multidimensional-array objectid

我正在尝试在ruby模块中执行类似的操作:

def initialize
  super
  @@main_array = Array.new(16) { Array.new} 
end

def add_hash(hash={})
  @@main_array[get_id] << hash
end
# Where get_id returns 0-15

我希望每个子数组只有添加到它的哈希值。相反,所有子阵列都添加了所有哈希值。检查数组显示子数组都共享对象ID。

我不确定为什么会这样。我在这里错过了什么?

修改

以下是我使用的确切代码:

module Manager
  def initialize
    super
    @@main_array = Array.new(BaseCompany.get_number_thread(), Array.new())
  end

  def self.check_and_add_thread_activity(activity={})
    action = Hash.new
    action[:id] = @@main_array[BaseCompany.get_current_threadid].length +1 
    action[:name] = activity[:name]
    action[:added] = true
    @@main_array[BaseCompany.get_current_threadid] << action
    return action
  end

end

Check_and_add由代码的其他部分调用,因为各个线程执行功能

好的,我实际上解决了它。在下面的评论中有人提到这个:

Array.new(16,Array.new)

会导致子数组具有相同的对象ID。有人纠正他说不应该发生,但我的代码就是这种情况。我用推荐的替换了那一行:

Array.new(16) {Array.new} 

这很好用。

供参考,我使用的是JRuby 1.7.3

1 个答案:

答案 0 :(得分:2)

Array.new(size,object)

main_array = Array.new(16, Array.new)

相当于:

row = Array.new
main_array = Array.new(16,row)

或只是

main_array = [row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row]

所以你有16次完全相同的对象(一个空数组)。修改一个元素将自动修改所有其他元素:

p main_array
#=> [[], [], [], [], [], [], [], [], [], [], [], [], [], [], [], []]

row << 1

p main_array
#=> [[1], [1], [1], [1], [1], [1], [1], [1], [1], [1], [1], [1], [1], [1], [1], [1]]

Array.new(size){}

main_array = Array.new(16){ Array.new }

相当于:

main_array = (1..16).map{ Array.new }

或:

main_array = [Array.new, Array.new, Array.new, Array.new, Array.new, Array.new, Array.new, Array.new, Array.new, Array.new, Array.new, Array.new, Array.new, Array.new, Array.new, Array.new]

现在你有16个空数组,但它们都是不同的对象。修改一个元素不会修改任何其他数组:

main_array = Array.new(16){ Array.new }

p main_array
#=> [[], [], [], [], [], [], [], [], [], [], [], [], [], [], [], []]

main_array[0] << 1

p main_array
#=> [[1], [], [], [], [], [], [], [], [], [], [], [], [], [], [], []]