-
我有一个嵌套的数据哈希:
munsters = { "Herman" => { "age" => 32, "gender" => "male" }, "Lily" => { "age" => 30, "gender" => "female" }, "Grandpa" => { "age" => 402, "gender" => "male" }, "Eddie" => { "age" => 10, "gender" => "male" }, "Marilyn" => { "age" => 23, "gender" => "female"} }
-
我想循环遍历每个成员的哈希,并在嵌套哈希中查找他们的年龄。
-
对于每个成员,我想在现有的嵌套散列中添加一个新的键值对,称为"age_group"。
-
每个成员的"年龄组"的值将取决于他们的年龄。例如,如果年龄在65岁以上,我想让他们的年龄组读成"老年人"等。
我遇到的问题:
当族中每个成员的第一个键不同时,我很困惑如何只访问嵌套哈希的"age"key_value对。也就是说,我不能做像munsters["age"]
这样的事情,因为它返回nil(假设因为嵌套了"age"(。
如果我有一个简单的(非嵌套的(散列,它是非常简单的。非嵌套散列示例:
ages = { "Herman" => 32, "Lily" => 30, "Grandpa" => 402, "Eddie" => 10 }
然后我可能会这样循环:
age_group = {}
ages.each do |k, v|
if v >= 65
puts "#{k}'s age of #{v} makes them a senior!"
age_group.merge!("age_group": "senior")
elsif v > 17 && v < 65
puts "#{k}'s age of #{v} makes them an adult"
age_group.merge!("age_group": "adult")
else
puts "#{k}'s age of #{v} makes them a kid."
age_group.merge!("age_group": "kid")
end
end
对于嵌套哈希,我可以访问整个嵌套哈希,如下所示:
munsters.each do |k, v|
v.each do |k2, v2|
p "k2 is #{k2} and v2 is #{v2}"
end
end
但这仍然只会将整个嵌套哈希返回到控制台,而不仅仅是年龄:
k2 is age and v2 is 32
k2 is gender and v2 is male
除了@MurifoX答案,您还可以使用#transform_values
ages.transform_values do |value|
if value["age"] >= 65
value["age_group"] = "senior"
elsif value["age"] > 17 && value["age"] < 65
value["age_group"] = "adult"
else
value["age_group"] = "kid"
end
end
v
也是一个散列。所以你可以这样做:
ages.each do |k, v|
if v["age"] > 60
ages[k]["age_group"] = "adult"
else
ages[k]["age_group"] = "kid"
end
end
将一个带有字符串值的age_group
密钥添加到年龄哈希的k
位置。
def age_group(age)
case age
when 0..17 then "kid"
when 18..64 then "adult"
else "senior"
end
end
munsters.each_value { |h| h["age_group"] = age_group(h["age"]) }
#=> {"Herman" =>{"age"=>32, "gender"=>"male", "age_group"=>"adult"},
# "Lily" =>{"age"=>30, "gender"=>"female", "age_group"=>"adult"},
# "Grandpa"=>{"age"=>402, "gender"=>"male", "age_group"=>"senior"},
# "Eddie" =>{"age"=>10, "gender"=>"male", "age_group"=>"kid"},
# "Marilyn"=>{"age"=>23, "gender"=>"female", "age_group"=>"adult"}}
此返回值是munsters
的新值。
当前尝试的问题是,您试图为每个munster
的每个键/值对做一些事情。但是,您只对"age"
和"age_group"
感兴趣。因此,不需要对munster
的键/值对进行迭代。相反,直接在munster
上工作。
其他例子大多显示了突变的解决方案,所以让我提供一个非突变的替代方案(意味着munsters
不会改变(。我还删除了if-语句,以提供另一种视角。
threshholds = { "kid" => 0, "adult" => 18, "senior" => 65 }
age_groups = threshholds.each_key.sort_by(&threshholds)
new_munsters = munsters.transform_values do |munster|
age_group = age_groups
.take_while { |age_group| munster["age"] > threshholds[age_group] }
.last
munster.merge("age_group" => age_group)
end
#=> {
# "Herman"=>{"age"=>32, "gender"=>"male", "age_group"=>"adult"},
# "Lily"=>{"age"=>30, "gender"=>"female", "age_group"=>"adult"},
# "Grandpa"=>{"age"=>402, "gender"=>"male", "age_group"=>"senior"},
# "Eddie"=>{"age"=>10, "gender"=>"male", "age_group"=>"kid"},
# "Marilyn"=>{"age"=>23, "gender"=>"female", "age_group"=>"adult"}
# }
此解决方案使用transform_values
创建munsters
的新版本,其中包含munster
的新更新版本(使用merge
创建(。