如何在ruby中使用map或group_by更改数组散列的输出?
我有一个散列数组,其中我必须分离相同的值对象,并根据日期按国家对其进行分组。 我尝试使用group_by,但我只能设法获得我无法分隔报告的_日期的国家/地区 在数组散列之外。 请注意,其中一个对象是相同的如何在ruby中使用map或group_by更改数组散列的输出?,ruby,api,Ruby,Api,我有一个散列数组,其中我必须分离相同的值对象,并根据日期按国家对其进行分组。 我尝试使用group_by,但我只能设法获得我无法分隔报告的_日期的国家/地区 在数组散列之外。 请注意,其中一个对象是相同的 "reported_date": "2020-04-01" 我希望它在每个散列之外,所以它只打印一次 这是我的杂烩 [ { "reported_date": "2020-04-01",
"reported_date": "2020-04-01"
我希望它在每个散列之外,所以它只打印一次
这是我的杂烩
[
{
"reported_date": "2020-04-01",
"country": "Italy",
"confirmed": 110574,
"deaths": 13155,
"recovered": 16847
},
{
"reported_date": "2020-04-01",
"country": "Spain",
"confirmed": 104118,
"deaths": 9387,
"recovered": 22647
},
{
"reported_date": "2020-04-01",
"country": "US",
"confirmed": 83948,
"deaths": 1941,
"recovered": 0
}
]
我想改变这样的事情
{
"reported_date": "2020-04-01",
"countries": [
{
"country": "Italy",
"confirmed": 110574,
"deaths": 13155,
"recovered": 16847
},
{
"country": "Spain",
"confirmed": 104118,
"deaths": 9387,
"recovered": 22647
},
{
"country": "US",
"confirmed": 83948,
"deaths": 1941,
"recovered": 0
}
]
}
[
{
“报告日期”:“2020-04-01”,
“国家”:“意大利”,
“确认”:110574,
“死亡”:13155,
“已恢复”:16847
},
{
“报告日期”:“2020-04-01”,
“国家”:“西班牙”,
“确认”:104118,
“死亡”:9387人,
“已恢复”:22647
},
{
“报告日期”:“2020-04-01”,
“国家”:“美国”,
“确认”:83948,
“死亡”:1941年,
“已恢复”:0
}
].group|u by{h | h[:reported|u date]}.map do|date,rest|
{
报告日期:日期,
国家:rest.map{| h | h.reject!{| k | k==:reported|u date}
}
结束
返回
[
{
:报告日期=>“2020-04-01”,
:国家=>[
{
:country=>“意大利”,
:已确认=>110574,
:死亡人数=>13155,
:已恢复=>16847
},
{
:country=>“西班牙”,
:已确认=>104118,
:死亡人数=>9387,
:已恢复=>22647
},
{
:country=>“美国”,
:已确认=>83948,
:死亡人数=>1941,
:已恢复=>0
}
]
}
]
假设您的数组是:
arr = [
{ date: "2020-04-01", country: "Italy", confirmed: 110574, deaths: 13155},
{ date: "2020-04-02", country: "Spain", confirmed: 104118, deaths: 9387},
{ date: "2020-04-01", country: "US", confirmed: 83948, deaths: 1941},
{ date: "2020-04-02", country: "Italy", confirmed: 120431, deaths: 13394}
]
根据您的需要,您可能会发现重新组织数据更方便,可能有以下两种方法之一
#1
keeper_keys = arr.first.keys - [:date, :country]
#=> [:confirmed, :deaths]
h = arr.each_with_object({}) { |g,h| h[g[:date]] =
(h[g[:date]] || {}).merge(g[:country]=>g.slice(*keeper_keys)) }
#=> {"2020-04-01"=>{
# "Italy"=>{:confirmed=>110574, :deaths=>13155},
# "US"=>{:confirmed=>83948, :deaths=>1941}
# },
# "2020-04-02"=>{
# "Spain"=>{:confirmed=>104118, :deaths=>9387},
# "Italy"=>{:confirmed=>120431, :deaths=>13394}
# }
# }
如果h
没有键,则h[g[:date]]|{}
返回一个空哈希值g[:date]
这使我们能够轻松计算,例如:
按日期和国家分列的死亡人数
截至日期的死亡总数
#2
keeper_keys = arr.first.keys - [:date, :country]
#=> [:confirmed, :deaths]
h = arr.each_with_object({}) { |g,h| h[g[:country]] =
(h[g[:country]] || {}).merge(g[:date]=>g.slice(*keeper_keys)) }
#=> {"Italy"=>{
# "2020-04-01"=>{:confirmed=>110574, :deaths=>13155},
# "2020-04-02"=>{:confirmed=>120431, :deaths=>13394}
# },
# "Spain"=>{
# "2020-04-02"=>{:confirmed=>104118, :deaths=>9387}
# },
# "US"=>{
# "2020-04-01"=>{:confirmed=>83948, :deaths=>1941}
# }
# }
h[g[:country]|{}
如果h
没有键,则返回空哈希值g[:country]
这使我们能够轻松计算:
按国家和日期分列的死亡人数
请注意,此表达式与之前用于按日期和国家获取死亡人数的表达式相同
截至日期的死亡总数
同样,这个表达式与之前用于计算各国总死亡人数的表达式相同
最好使用数据库 有一个错误
未定义的方法
除了“for#我误以为你在使用Rails”。更新了答案“不依赖Rails”。实际上,我使用的是Rails,这就是输出。事实上,我对你的答案做了一点修改,因为你仍然拒绝或排除输出id并创建了。我使用map然后打印我需要的单个对象如果需要属性的白名单,我建议使用Hash#slice代码>。无论如何,如果这对你有帮助,考虑一下投票和/或接受答案。
p.transform_values { |g| g.values.sum }
#=> {"2020-04-01"=>15096, "2020-04-02"=>22781}
keeper_keys = arr.first.keys - [:date, :country]
#=> [:confirmed, :deaths]
h = arr.each_with_object({}) { |g,h| h[g[:country]] =
(h[g[:country]] || {}).merge(g[:date]=>g.slice(*keeper_keys)) }
#=> {"Italy"=>{
# "2020-04-01"=>{:confirmed=>110574, :deaths=>13155},
# "2020-04-02"=>{:confirmed=>120431, :deaths=>13394}
# },
# "Spain"=>{
# "2020-04-02"=>{:confirmed=>104118, :deaths=>9387}
# },
# "US"=>{
# "2020-04-01"=>{:confirmed=>83948, :deaths=>1941}
# }
# }
p = h.transform_values { |g| g.transform_values { |f| f[:deaths] } }
#=> {"Italy"=>{"2020-04-01"=>13155, "2020-04-02"=>13394},
# "Spain"=>{"2020-04-02"=>9387},
# "US"=>{"2020-04-01"=>1941}}
p.transform_values { |g| g.values.sum }
#=> {"Italy"=>26549, "Spain"=>9387, "US"=>1941}