2017-09-20 20 views
0

私はファイルから入力を読み込むコードを書いています。2次元配列が上書きされるべきでないときに上書き

私のコードは入力ファイルの内容を解析し、そのデータを2D配列として格納します。

入力されている(私はここで動作するように書式設定を取得することはできません、正しい書式については、以下の入力ファイルを参照してください):


ABC DEF

G


2次元配列を解析すると、次のようになります。 [['A

私が問題にしていることは、何らかの形で以前の要素が上書きされているということです2D配列内で、次のエントリ、例えば

[[ 'G']、[ 'G']、[ 'G']]

2D配列がすべきと書き込みとして、私は、それを見てきたが、これが起こっているかを確認することはできません新しいエントリごとに1回だけ発生し、新しいデータを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..." 
+0

'px'はデバッグに使用することを意図しています。これは' 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_array'のメモリ内の別の場所に格納されていると考えました。データのソースへのポインタではありません。 'p @ command_array.map(&:object_id)'のコード行も本当に便利です。もう一度使用してください。このようなものが呼び出されたときにメモリ内のどこかに座っていることを覚えていなければなりません;)本当に有益でよく分かりやすい答えです。 – TheLemonSong

関連する問題