`each_with_object(Hash.new([]))` 是如何工作的?
How does `each_with_object(Hash.new([]))` work?
我编写这段代码是为了创建一个散列,其中键是类别(水果或蔬菜),值是该类别中的项目数组。
food = ["fruit:orange", "fruit:apple", "fruit:cherry", "veg:pea", "veg:parsley"]
food.each_with_object(Hash.new([])) do |food_item, hash|
category, value = food_item.split(":")
hash[category] = hash[category].push(value)
end
这是我得到的:
# =>
{
"fruit" => ["orange", "apple", "cherry", "pea", "parsley"],
"veg" => ["orange", "apple", "cherry", "pea", "parsley"]
}
但我预料到了这一点:
{
"fruit"=> ["orange", "apple", "cherry"],
"veg" => ["pea", "parsley"]
}
第一次迭代应该生成 { fruit: ["orange"] }
,第二次迭代 { fruit: ["orange", "apple"] }
等等...第四次迭代应该创建 veg 键,然后继续。蔬菜如何最终被推到水果数组,反之亦然?
哇,评论里充满了莎士比亚的热情。好吧,我可以重现一个问题,我会提供一个答案。
根据 Hash#new
上的文档:
If obj is specified, this single object will be used for all default values.
也就是说,所有新创建的散列元素将共享数组的唯一实例。换句话说,根据规范,在这种情况下,您的哈希值根据定义将始终相同。要产生您最初想要的结果,只需在每次需要时使用 new 空实例 Array
:
初始化散列值
food = ["fruit:orange", "fruit:apple", "fruit:cherry", "veg:pea", "veg:parsley"]
food.each_with_object({}) do |food_item, hash|
category, value = food_item.split(":")
(hash[category] ||= []).push(value)
end
#⇒ {"fruit"=>["orange", "apple", "cherry"], "veg"=>["pea", "parsley"]}
散列数组["fruit"]和散列数组["veg"]是完全相同的对象。
您需要像这样为每个键创建新数组。
food.each_with_object(Hash.new{|h,k| h[k]=[]}) do |food_item, hash|
category, value = food_item.split(":")
hash[category] = hash[category].push(value)
end
我编写这段代码是为了创建一个散列,其中键是类别(水果或蔬菜),值是该类别中的项目数组。
food = ["fruit:orange", "fruit:apple", "fruit:cherry", "veg:pea", "veg:parsley"]
food.each_with_object(Hash.new([])) do |food_item, hash|
category, value = food_item.split(":")
hash[category] = hash[category].push(value)
end
这是我得到的:
# =>
{
"fruit" => ["orange", "apple", "cherry", "pea", "parsley"],
"veg" => ["orange", "apple", "cherry", "pea", "parsley"]
}
但我预料到了这一点:
{
"fruit"=> ["orange", "apple", "cherry"],
"veg" => ["pea", "parsley"]
}
第一次迭代应该生成 { fruit: ["orange"] }
,第二次迭代 { fruit: ["orange", "apple"] }
等等...第四次迭代应该创建 veg 键,然后继续。蔬菜如何最终被推到水果数组,反之亦然?
哇,评论里充满了莎士比亚的热情。好吧,我可以重现一个问题,我会提供一个答案。
根据 Hash#new
上的文档:
If obj is specified, this single object will be used for all default values.
也就是说,所有新创建的散列元素将共享数组的唯一实例。换句话说,根据规范,在这种情况下,您的哈希值根据定义将始终相同。要产生您最初想要的结果,只需在每次需要时使用 new 空实例 Array
:
food = ["fruit:orange", "fruit:apple", "fruit:cherry", "veg:pea", "veg:parsley"]
food.each_with_object({}) do |food_item, hash|
category, value = food_item.split(":")
(hash[category] ||= []).push(value)
end
#⇒ {"fruit"=>["orange", "apple", "cherry"], "veg"=>["pea", "parsley"]}
散列数组["fruit"]和散列数组["veg"]是完全相同的对象。
您需要像这样为每个键创建新数组。
food.each_with_object(Hash.new{|h,k| h[k]=[]}) do |food_item, hash|
category, value = food_item.split(":")
hash[category] = hash[category].push(value)
end