哈希没有被添加到数组中

时间:2017-01-20 22:03:52

标签: ruby

我放弃了,我不知道为什么我创建的哈希值没有被添加到数组的末尾。当我pp哈希它是正确的,但由于某种原因,第一个哈希变得重复,而第二个哈希没有被添加..

我得到的结果是:

[{:id=>"36757153479", :quantity=>1, :status=>"new"}, 
{:id=>"36757153479", :quantity=>1, :status=>"new"}]
#notice that the id is the same

虽然我想要的是这个:

[{:id=>"36767751239", :quantity=>1, :status=>"new"},
{:id=>"36757153479", :quantity=>1, :status=>"new"}]

传入的数组如下所示:

me = [{"id"=>36767751239, "quantity"=>1,"vendor"=>"Martha
Stewart", "product_id"=>9707911431, "gift_card"=>false}, {"id"=>36757153479,
"quantity"=>1, "vendor"=>"Naturalizer", "product_id"=>9707504007,
"gift_card"=>false}]

我的代码就是这样:

incoming_cart_array = []
incoming_cart_hash = {}
unless me.nil?
  me.each do |product|
    incoming_cart_hash[:id] = product['variant_id'].to_s
    incoming_cart_hash[:quantity] = product['quantity']
    incoming_cart_hash[:status] = "new"
    incoming_cart_array << incoming_cart_hash
  end
end

我已经做了100多次这样的事情,但不知怎的,这不起作用。它可能就在我面前,我只是无法看到它。

由于

2 个答案:

答案 0 :(得分:3)

我似乎能够解决它

incoming_cart_array = []
unless me.nil?
  me.each do |product|
    incoming_cart_hash = {}
    incoming_cart_hash[:id] = product['id'].to_s
    incoming_cart_hash[:quantity] = product['quantity']
    incoming_cart_hash[:status] = "new"
    incoming_cart_array << incoming_cart_hash
  end
end

然而,我似乎无法找到原因,当它没有在同一范围内定义时,它无法覆盖incoming_cart_hash [:id]。 如果我搞清楚的话,我会深入研究并更新我的答案!

编辑:我的第一个初始版虽然经过一些调试后,当哈希不是局部变量时,它被定义(在Ruby Source中,这是基于C的),作为指向哈希类型的指针。因此,在array << hash行中,您将插入指向数组中哈希的指针。当您运行me.each n次(在这种情况下为2)时,哈希值会更新,因此您将拥有n - 数组中的指针,所有指针都指向同一个元素。您正在更新的哈希。它被视为同一个红宝石对象。

如果你在循环中输出incoming_cart_hash.object_id,每次,当哈希定义在循环之外时,你会看到object_id是相同的。但是,当它在里面 - 每次定义为一个新的局部变量时,它会有所不同,因为它每次都是一个新的和重新定义的对象。

我在这里找到了一些关于它的说明:Ruby - Parameters by reference or by value?

答案 1 :(得分:1)

您的代码只会创建一个{},因此您获得的数组的哈希值为n倍。

您必须为每次迭代创建一个新的{}

incoming_cart_array = []
unless me.nil?
  me.each do |product|
    incoming_cart_hash = {}
    ...
  end
end

Pro tipp - Ruby中的最佳实践是使用map从数组创建和数组。您可以使用文字语法创建新哈希,并使用&&检查nil案例。

incoming_cart_array = me && me.map do | product | 
  {
    id: product['id'].to_s,
    quantity: product['quantity'],
    status: "new",
  }
end