我的数据如下:
[
{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']}]},
]
答案 0 :(得分:4)
试试这个:
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"]}]}}]
答案 1 :(得分: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
的每个元素中:node
和arr
的值对应的键值对的哈希。我选择使用Hash#update(aka 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"}}
在继续格式化步骤之前,我应该指出,根据需求,在后续计算中使用此哈希可能更方便,而不是请求的数组。
,格式化现在非常简单h.map { |d,g| { d=>{groups: [g] } } }
#=> [{"2014/10/01"=>{:groups=>[{"a"=>"2", "b"=>"3"}]}},
# {"2014/10/02"=>{:groups=>[{"a"=>"4", "b"=>"1"}]}}]