[英]How to nest an array of hashes with group by as json?
我有看起来像这样的数据:
[
{date: '2014/10/01', group: 'a', node: '2'},
{date: '2014/10/01', group: 'b', node: '3'},
{date: '2014/10/02', group: 'a', node: '4'},
{date: '2014/10/02', group: 'b', node: '1'}
]
我将如何按日期先进行分组,如下所示:
.group_by{|x| [x.date.strftime("%Y-%m-%d")}
但是然后按group
,然后按node
并将其呈现为嵌套的json?
我正在寻找这样的东西:
[
{'2014/10/01': {groups: [{a: ['2'], b: ['3']}]},
{'2014/10/02': {groups: [{a: ['4'], b: ['1']}]},
]
尝试这个:
arr = [
{date: '2014/10/01', group: 'a', node: '2'},
{date: '2014/10/01', group: 'b', node: '3'},
{date: '2014/10/02', group: 'a', node: '4'},
{date: '2014/10/02', group: 'b', node: '1'}
]
arr.group_by { |item| item[:date] }.map do |k,v|
Hash[k, { groups: v.map { |g| Hash[g[:group], [g[:node]]] }}]
end
# => [{"2014/10/01"=>{:groups=>[{"a"=>["2"]}, {"b"=>["3"]}]}}, {"2014/10/02"=>{:groups=>[{"a"=>["4"]}, {"b"=>["1"]}]}}]
当遇到这样的问题,涉及到数据的多次转换时,我经常发现将问题分为两个步骤很有用,第一步是创建一个包含所有基本信息的数组或哈希。 第二个是将数据格式化为所需的格式。
最好围绕一个示例来描述该过程。 问题中给出的一个很好:
arr = [
{date: '2014/10/01', group: 'a', node: '2'},
{date: '2014/10/01', group: 'b', node: '3'},
{date: '2014/10/02', group: 'a', node: '4'},
{date: '2014/10/02', group: 'b', node: '1'}
]
由于我们将对日期进行分组,因此将数据从arr
提取到键为日期的哈希中是很有意义的。 这些键的值是散列,包含与arr
每个元素中的:group
和:node
值相对应的键值对。 我选择使用Hash#update的形式(也称为merge!
)来执行此操作,该形式使用一个块来确定要合并的两个哈希中存在的键的值:
h = arr.each_with_object({}) { |g,h|
h.update(g[:date]=>{ g[:group]=>g[:node] }) { |_,oh,nh|oh.update(nh) } }
#=> {"2014/10/01"=>{"a"=>"2", "b"=>"3"},
# "2014/10/02"=>{"a"=>"4", "b"=>"1"}}
在继续进行格式化步骤之前,我应该指出,根据要求,在后续的计算中使用此哈希值可能比请求的数组更方便。
现在可以使用Enumerable#map进行格式化:
h.map { |d,g| { d=>{groups: [g] } } }
#=> [{"2014/10/01"=>{:groups=>[{"a"=>"2", "b"=>"3"}]}},
# {"2014/10/02"=>{:groups=>[{"a"=>"4", "b"=>"1"}]}}]
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.