【问题标题】:2D Array Overwritten When It Shouldn't Be二维数组不应该被覆盖
【发布时间】:2018-03-01 19:36:10
【问题描述】:

我正在编写一些从文件中读取输入的代码。

我的代码解析输入文件的内容并将数据存储为二维数组,例如

输入是(请参阅下面的输入文件以了解正确的格式,我无法在此处进行格式设置):


ABC

防御

G


解析后的二维数组应该是这样的... [['A','B','C',],['D','E','F'],['G']]

我遇到的问题是,以前的元素以某种方式被写入二维数组中,并带有后续条目,例如

[['G'],['G'],['G']]

我已经查看了它,但看不到这是如何发生的,因为对 2D 数组的写入应该只在每个新条目发生一次,然后它们应该只在将新数据附加到 2D 数组时发生,并且不覆盖以前的条目。

我有点卡住了,你们中有人知道为什么会这样吗?

谢谢!:)

代码

    class Reader

    def initialize
        @command_array = Array.new { Array.new } # 2D array

    end

      def run(file)
        return puts "please provide correct file" if file.nil? || !File.exists?(file)

        command_line = Array.new            #Temp array
        p "----------------------------------------------------------------"
        File.open(file).each do |line|     
          p "looking at a line of commands..."
          line.split(' ').each do |command| 
            p "storing the command #{command} in temp array"
            command_line.push(command)
            p command_line
          end

          p "Storing the temp array as an element in the 2d array..."
          @command_array.push(command_line)
          p @command_array

          p "Clearing the temp array..."
          p "----------------------------------------------------------------"
          command_line.clear
        end
      end
    end
#

输入文件

A B C
D E F
G
#

输出

    "looking at a line of commands..."
    "storing the command A in temp array"
    ["A"]
    "storing the command B in temp array"
    ["A", "B"]
    "storing the command C in temp array"
    ["A", "B", "C"]
    "Storing the temp array as an element in the 2d array..."
    [["A", "B", "C"]]
    "Clearing the temp array..."
    "----------------------------------------------------------------"
    "looking at a line of commands..."
    "storing the command D in temp array"
    ["D"]
    "storing the command E in temp array"
    ["D", "E"]
    "storing the command F in temp array"
    ["D", "E", "F"]
    "Storing the temp array as an element in the 2d array..."
    [["D", "E", "F"], ["D", "E", "F"]]
    "Clearing the temp array..."
    "----------------------------------------------------------------"
    "looking at a line of commands..."
    "storing the command G in temp array"
    ["G"]
    "Storing the temp array as an element in the 2d array..."
    [["G"], ["G"], ["G"]]
    "Clearing the temp array..."
#

【问题讨论】:

  • p x 用于调试,相当于puts x.inspect。您应该使用puts 显示提示,这样可以避免使用引号。
  • 嘿@tadman,感谢您的意见。我只是使用“p”作为将数组内容扔到屏幕上的快速方法。再次感谢您查看此内容:)

标签: arrays ruby multidimensional-array


【解决方案1】:

问题是您已经竭尽全力为您解析的每一行回收相同的数组。请记住,在 Ruby 中,Array#push 将对象引用(指针)指向您要推送的数组,因此对该对象的任何修改都会影响对它的所有引用。

你的程序的一个更简单的形式是:

class Reader
  def initialize
    @command_array = [ ]
  end

  def run(file)
    @command_array = File.readlines(file).map do |line|
      line.chomp.split(' ')
    end
  end
end

您对Array.new { Array.new } 的初始分配并不是很有用,第二个参数是默认值,它从未使用过,因为您只将push 放入其中。在 Ruby 中没有必要以这种方式强类型化。数组只是一个数组,散列只是一个散列,它们不需要以任何特定的形式初始化就可以以任何特定的方式使用。 array[0]['hash_key'] 可以与array[1][2] 在同一对象上同时有效。

每当您遇到与克隆对象类似的问题时,它们会以某种方式纠缠并且更改为一个对象会影响其他对象,您可能无意中使用了同一个对象。要查看 Ruby 将您的数组视为什么用途:

p @command_array.map(&:object_id)

这将显示其中有哪些对象标识符。在你的情况下,它们都是相同的。

【讨论】:

  • 嘿再次@tadman。很好的答案:) 你提到的指针现在完全有意义。我认为存储“命令”变量的每次迭代都将存储在“command_array”中内存中的单独位置,但事实并非如此,只是指向数据源的指针。 'p @command_array.map(&:object_id)' 行代码也非常有用,我一定会再次使用它。必须记住所有这些东西在被调用时位于内存中的某个地方;)再次感谢,一个非常翔实且清晰的答案!:)
猜你喜欢
  • 1970-01-01
  • 2013-03-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-09
  • 2018-01-29
  • 1970-01-01
  • 2015-05-27
相关资源
最近更新 更多