如何在ruby中使用map或group_by更改数组散列的输出?

如何在ruby中使用map或group_by更改数组散列的输出?,ruby,api,Ruby,Api,我有一个散列数组,其中我必须分离相同的值对象,并根据日期按国家对其进行分组。 我尝试使用group_by,但我只能设法获得我无法分隔报告的_日期的国家/地区 在数组散列之外。 请注意,其中一个对象是相同的 "reported_date": "2020-04-01" 我希望它在每个散列之外,所以它只打印一次 这是我的杂烩 [ { "reported_date": "2020-04-01",

我有一个散列数组,其中我必须分离相同的值对象,并根据日期按国家对其进行分组。 我尝试使用group_by,但我只能设法获得我无法分隔报告的_日期的国家/地区 在数组散列之外。 请注意,其中一个对象是相同的

"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}