2017-09-20 175 views
0

我在寫一些從文件讀取輸入的代碼。二維數組不應該被覆蓋

我的代碼解析輸入文件的內容並將數據存儲爲二維數組,例如,

的輸入(請參閱下面的正確的格式輸入文件,我不能格式化在這裏工作):


ABC

DEF


解析2D數組後應該看起來像這樣... [['A 」, 'B', 'C'],[ 'd', 'E', 'F'],[ 'G']]

我的問題是,在某種程度上先前元素被寫在在二維數組中有後續的條目,例如

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

我已經通過它看上去卻無法看到這是如何發生的,因爲寫入二維數組應每個新條目只會出現一次,然後它們只能在將新數據附加到二維數組時纔會發生,而不會覆蓋以前的條目。

我有點卡住了,你們有沒有任何想法,爲什麼會發生這種情況?

謝謝!:)

代碼

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..." 
+0

'p x'旨在用於調試,它相當於'puts x.inspect'。你應該用'puts'顯示提示,避免引號。 – tadman

+1

嘿@tadman,謝謝你的輸入。我只是使用'p'作爲快速的方式來拋出數組的內容。再次感謝您看這個:) – TheLemonSong

回答

3

問題是你已經走出了自己的方式來回收你解析每一行相同的數組。在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) 

這將顯示哪些對象標識符都在那裏。在你的情況下,他們都是相同的。

+1

再次@tadman。很好的回答:)你用指針提到的東西現在完全有意義。我認爲存儲'command'變量的每次迭代都將存儲在'command_array'的內存中的一個單獨位置,而不是它,只是指向數據源的指針。 'p @ command_array.map(&:object_id)'代碼行也非常有用,我一定會再次使用它。一定要記住所有這些東西都在記憶中的某個地方;)再次感謝,一個非常豐富和明確的答案!:) – TheLemonSong