2017-08-07 18 views
0

私は上書きせずに配列にプッシュする必要があるこれらのハッシュを出力として持っています。配列へのハッシュのプッシュ

output1= {:user_id=>9, :project_id=>4, :task_id=>87, :comment=>"Test 20"} 
output2 = {:user_id=>9, :project_id=>12, :task_id=>105,:comment=>"Test 21"} 

ループを反復処理するときに、これら2つの出力を1つの配列にプッシュする必要があります。今起こっていることは、2番目の出力を配列にプッシュすると、最初の出力を上書きしてしまうことです。

Entry_array=[{:user_id=>9,:project_id=>12,:task_id=>105,:comment=>"Test 21"}, 
{:user_id=>9, :project_id=>12, :task_id=>105,:comment=>"Test 21"}] 

ハッシュ出力1とハッシュ出力2の結果を結合したい。 ありがとうございました。

これは、私は、これはあなたが探しているものだと思う私は

attributes =[:user_id,:project_id,task_id,:comment] 
    entry_array=[] 
    output = {} 

    CSV.foreach(csv_file, headers: true, converters: :date).with_index do |row,line_no| 
    entry_hash= row.to_hash 
    .....some code here where we get the entry_hash.... 
    i=0 

    entry_array <<output 
    end 
+1

いくつかのコードを表示してください(例:ループを繰り返しているところなど)。 – jvillian

+1

もう少しコードが必要だと思います。'i'はどこに定義されていますか? 'entry_hash'とは何ですか? '出力 'とは何ですか? '属性'とは何ですか? –

答えて

2

あなたが同じoutputハッシュを使用しているので、これが起こっている理由は、少なくともあなたのコードに応じてあります各行。実行した場合、CSVファイルの最後に

puts entry_array.collect(&:object_id) 

が表示されますが、すべて同じオブジェクトであることがわかります。したがって、各行の最後の配列に配置しても、配列が現在指している同じオブジェクトがまだ変更されています。基本的に何をやっていることは、あなたがこの問題を解決するために必要な何

a = { hello: 'world' } # => {:hello=>"world"} 
b = a     # => {:hello=>"world"} 
b[:hello] = 'there' 
a      # => {:hello=>"there"} 
b      # => {:hello=>"there"} 

# storing it in an array does the same thing 
output = { hello: 'world' } # => {:hello=>"world"} 
array = [output]   # => [{:hello=>"world"}] 
output[:hello] = 'there' 
output      # => {:hello=>"there"} 
array      # => [{:hello=>"there"}] 

ある行ごとに、新しいハッシュをインスタンス化である:

attributes = [:user_id, :project_id, :task_id, :comment] 
entry_array = [] 

CSV.foreach(csv_file, headers: true, converters: :date).with_index do |row, line_no| 
    output = { } # Instantiate here, inside the loop, so each row gets its own hash 
    entry_hash = row.to_hash 

    # if you need the key for something, use this 
    # entry_hash.each.with_index do |(key, value), index| 
    # otherwise, just iterate over each value 
    entry_hash.each_value.with_index do |value, index| 
    output[attributes[index]] = value.is_a?(Array) ? value.first.to_i : value 
    end 

    entry_array << output 
end 

私はis_a?にあなたのクラスのチェックを変更しましたし、また、 iカウンタを削除して、with_indexを繰り返し使用しましたが、表示されたサンプルでkeyを使用していなかったので、each_valueを使用しましたが、使用している場合はとeach_indexを使用する方法を示すコメントを残しました。 keyは示されていません。

+0

ありがとう!出来た – Archie123

0

私はこれがあなたの夢をかなえるための最良の方法であるかわからないが、それはあなたがあなたの配列を持っていることを今の方法

1)を作成し、あなたの配列

arr_of_hashes = []

2)でありますあなたはarr_of_hashesの値を検査する際

output1= {:user_id=>9, :project_id=>4, :task_id=>87, :comment=>"Test 20"} 
output2 = {:user_id=>9, :project_id=>12, :task_id=>105,:comment=>"Test 21"} 

arr_of_hashes << output1 
arr_of_hashes << output2 
... 

3)今、あなたは

を取得する、あなたのハッシュを移入することができます

[{:user_id=>9, :project_id=>4, :task_id=>87, :comment=>"Test 20"}, {:user_id=>9, :project_id=>12, :task_id=>105, :comment=>"Test 21"}]

私はこのことができますことを願っています:)

ハッピーハッキング

CSV.foreach(csv_file, headers: true, converters: :date).with_index do |row,line_no| 

.....some code here where we get the entry_hash.... 

    entry_array = [] # you need to define the element first before you can add stuff to it :) 
    entry_hash.each do |key,value| 
     if value.class == Array 
      output[attributes[i]] = value.first.to_i 
     else 
      output[attributes[i]] = value 
     end 
     i += 1 
    end 
    entry_array <<output 
    end 
関連する問題