【问题标题】:Pushing hash into array将哈希推入数组
【发布时间】:2017-08-07 17:57:44
【问题描述】:

我将这些哈希值作为输出,我需要将其推入数组而不被覆盖。

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"}]

我想要组合散列输出 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 

【问题讨论】:

  • 请显示一些代码(例如,您“循环遍历”的位置)。
  • 我认为它需要更多的代码。 i 在哪里定义? entry_hash 是什么? output 是什么? attributes 是什么?

标签: ruby-on-rails ruby ruby-on-rails-4


【解决方案1】:

至少根据您的代码,发生这种情况的原因是因为您对每一行使用相同的 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_indexeach,如果您使用的是key,则未显示。

【讨论】:

    【解决方案2】:

    我认为这就是您要查找的内容:https://apidock.com/ruby/Enumerator/each_with_index。 我猜你使用的 i 在迭代之间会被刷新:)。

    【讨论】:

      【解决方案3】:

      我不确定这是实现梦想的最佳方式,但这是一种方式

      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 的值时,您将得到 ​​p>

      [{:user_id=&gt;9, :project_id=&gt;4, :task_id=&gt;87, :comment=&gt;"Test 20"}, {:user_id=&gt;9, :project_id=&gt;12, :task_id=&gt;105, :comment=&gt;"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 
      

      【讨论】:

        猜你喜欢
        • 2011-09-01
        • 2018-11-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-07-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多