繁体   English   中英

如何使用group by作为JSON嵌套哈希数组?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM