简体   繁体   English

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

[英]How to nest an array of hashes with group by as json?

I have data that looks like this: 我有看起来像这样的数据:

[
  {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'}
]

How would I go about first grouping by date like so: 我将如何按日期先进行分组,如下所示:

.group_by{|x| [x.date.strftime("%Y-%m-%d")}

but then by group and then node and render that as a nested json? 但是然后按group ,然后按node并将其呈现为嵌套的json?

I'm looking for something like this: 我正在寻找这样的东西:

[
  {'2014/10/01': {groups: [{a: ['2'], b: ['3']}]},
  {'2014/10/02': {groups: [{a: ['4'], b: ['1']}]},
]

Try this: 尝试这个:

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

When faced with problems like this one, involving multiple transformations to the data, I often find it useful to divide the problem into two steps, the first being to create an array or hash that contains all the essential information; 当遇到这样的问题,涉及到数据的多次转换时,我经常发现将问题分为两个步骤很有用,第一步是创建一个包含所有基本信息的数组或哈希。 the second being to format that data in the form desired. 第二个是将数据格式化为所需的格式。

It's best to describe the procedure around an example. 最好围绕一个示例来描述该过程。 The one given in the question is fine: 问题中给出的一个很好:

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'}
]

As we will be grouping on the date, it makes sense to extract the data from arr into a hash whose keys are dates. 由于我们将对日期进行分组,因此将数据从arr提取到键为日期的哈希中是很有意义的。 The values of those keys are hashes that contain key-value pairs corresponding to the values of :group and :node in each element of arr . 这些键的值是散列,包含与arr每个元素中的:group:node值相对应的键值对。 I've chosen to do that using the form of Hash#update (aka merge! ) that uses a block to determine the values of keys that are present in both hashes being merged: 我选择使用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"}}

Before moving on to the formatting step, I should point out that, depending on requirements, it may more convenient to use this hash in subsequent calculations, rather than the array requested. 在继续进行格式化步骤之前,我应该指出,根据要求,在后续的计算中使用此哈希值可能比请求的数组更方便。

Formatting is now straightforward, using Enumerable#map : 现在可以使用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