下一个 key/value 对覆盖散列中的现有对,同时尝试使用新密钥添加对
Next key/value pair overwrites the existing pair in a hash while trying to add pair with new key
我有:
fruits = {
"orange" => {:season => "winter"},
"apple" => {:season => "winter"},
"banana" => {:season => "summer"},
"grape" => {:season => "spring"},
"peach" => {:season => "winter"},
"pineapple" => {:season => "summer"}
}
我想得到:
{
"winter"=>["orange", "apple", "peach"],
"summer"=>["banana", "pineapple"],
"spring"=>["grape"]
}
我做到了:
def sort_fruits(fruits_hash)
fruits=[]
sorted = {}
seasons = fruits_hash.map {|k, v|v[:season]}
seasons.uniq.each do |season|
fruits.clear
fruits_hash.each do |fruit, season_name|
if season == season_name[:season]
fruits << fruit
end
end
p sorted[season] = fruits ## season changes to new season, so this should have created new key/value pair for new season.
end
sorted
end
我得到:
{
"winter"=>["grape"],
"summer"=>["grape"],
"spring"=>["grape"]
}
我不明白为什么添加具有唯一键的新 key/value 对会覆盖散列中的现有对。任何解释方面的帮助将不胜感激。
您的问题是您对所有值重复使用相同的 fruits
数组。即使你清除它,它仍然是同一个数组。如果您使用 fruits = []
而不是 fruits.clear
,那么您就不会有问题。
您可以通过以下示例查看问题:
arr = ['val']
hash = {
key1: arr,
key2: arr
}
p hash # => { key1: ['val'], key2: ['val'] }
arr.clear
p hash # => { key1: [], key2: [] }
您也可以使用 sorted[season] = fruits.clone
或 sorted[season] = [*fruits]
...任何使用新数组的东西。
您必须跟踪何时使用 'mutation' 方法(那些就地更改对象的方法,例如 clear
)- 这是使用散列和数组时的常见陷阱
在 Ruby 中,可变对象通过引用传递。这意味着当您在 each
中迭代 seasons
时,请阻止此行:
sorted[season] = fruits
将每个季节的 fruits
引用保存到 sorted[season]
。在 each
循环完成后,每个季节都会引用同一个 fruits
数组,其中包含在迭代器的最后一步计算的项目。在您的情况下,它是 ["grape"]
.
我有:
fruits = {
"orange" => {:season => "winter"},
"apple" => {:season => "winter"},
"banana" => {:season => "summer"},
"grape" => {:season => "spring"},
"peach" => {:season => "winter"},
"pineapple" => {:season => "summer"}
}
我想得到:
{
"winter"=>["orange", "apple", "peach"],
"summer"=>["banana", "pineapple"],
"spring"=>["grape"]
}
我做到了:
def sort_fruits(fruits_hash)
fruits=[]
sorted = {}
seasons = fruits_hash.map {|k, v|v[:season]}
seasons.uniq.each do |season|
fruits.clear
fruits_hash.each do |fruit, season_name|
if season == season_name[:season]
fruits << fruit
end
end
p sorted[season] = fruits ## season changes to new season, so this should have created new key/value pair for new season.
end
sorted
end
我得到:
{
"winter"=>["grape"],
"summer"=>["grape"],
"spring"=>["grape"]
}
我不明白为什么添加具有唯一键的新 key/value 对会覆盖散列中的现有对。任何解释方面的帮助将不胜感激。
您的问题是您对所有值重复使用相同的 fruits
数组。即使你清除它,它仍然是同一个数组。如果您使用 fruits = []
而不是 fruits.clear
,那么您就不会有问题。
您可以通过以下示例查看问题:
arr = ['val']
hash = {
key1: arr,
key2: arr
}
p hash # => { key1: ['val'], key2: ['val'] }
arr.clear
p hash # => { key1: [], key2: [] }
您也可以使用 sorted[season] = fruits.clone
或 sorted[season] = [*fruits]
...任何使用新数组的东西。
您必须跟踪何时使用 'mutation' 方法(那些就地更改对象的方法,例如 clear
)- 这是使用散列和数组时的常见陷阱
在 Ruby 中,可变对象通过引用传递。这意味着当您在 each
中迭代 seasons
时,请阻止此行:
sorted[season] = fruits
将每个季节的 fruits
引用保存到 sorted[season]
。在 each
循环完成后,每个季节都会引用同一个 fruits
数组,其中包含在迭代器的最后一步计算的项目。在您的情况下,它是 ["grape"]
.