我将这些哈希作为输出,我需要将其推入数组而不会覆盖。
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个输出推送到单个数组中。现在发生的事情是,当我将第二个输出推入数组时,它会覆盖第一个输出,而下面是我得到的结果。
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"}]
我希望将hash output1和hash output2的结果组合在一起。 谢谢你的帮助。
这是我正在使用的代码
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
答案 0 :(得分:2)
这种情况发生的原因,至少根据您的代码,因为您对每一行使用相同的output
哈希。如果你跑了
puts entry_array.collect(&:object_id)
在CSV文件的末尾,您会看到它们都是同一个对象。因此,即使您将其放入每行末尾的数组中,您仍然在修改同一个对象,该数组现在指向该对象。基本上你正在做的是
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
,则会在哈希上留下评论,说明如何将each
与key
一起使用没有显示。
答案 1 :(得分:1)
我认为这正是您所寻找的:https://apidock.com/ruby/Enumerator/each_with_index。
我猜你使用的i
会在迭代之间刷新:)。
答案 2 :(得分:0)
我不确定这是让梦想成真的最好方法,但这是一种方式
1)创建你的数组
arr_of_hashes = []
2)现在您已拥有阵列,可以使用哈希填充它
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)现在当你检查arr_of_hashes的值时,你会得到
[{: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