以给定格式在Ruby中解析json的最佳方法

以给定格式在Ruby中解析json的最佳方法,ruby,Ruby,对于我的rails应用程序,将以以下格式接收SQL查询结果 @data= JSON.parse(request,symbolize_names: true)[:data] # @data sample [{"time":"2017-11-14","A":0,"B":0,"C":0,"D":0,"E":0}, {"time":"2017-11-15","A":0,"B":0,"C":0,"D":0,"E":0}, {"time":"2017-11-16","A":2,"B":

对于我的rails应用程序,将以以下格式接收SQL查询结果

   @data= JSON.parse(request,symbolize_names: true)[:data] 
#  @data sample

 [{"time":"2017-11-14","A":0,"B":0,"C":0,"D":0,"E":0},
  {"time":"2017-11-15","A":0,"B":0,"C":0,"D":0,"E":0},
  {"time":"2017-11-16","A":2,"B":1,"C":1,"D":0,"E":1},
  {"time":"2017-11-17","A":0,"B":0,"C":1,"D":0,"E":1},
  {"time":"2017-11-20","A":0,"B":0,"C":0,"D":0,"E":0},
  {"time":"2017-11-21","A":6,"B":17,"C":0,"D":0,"E":1}]
但是我想要数据的格式

  [{"name":"A","data":{"2017-11-16":2,"2017-11-21":6}},
  {"name":"B","data":{"2017-11-16":1,"2017-11-21":17}},
  {"name":"C","data":{"2017-11-16":1,"2017-11-17":1}},
  {"name":"D","data":{}},
  {"name":"E","data":{"2017-11-16":1,"2017-11-17":1,"2017-11-21":1}}]
在Ruby中解析这个的最佳方法是什么? 我尝试过使用@data.each方法,但很长


我对Ruby完全陌生。任何帮助都将不胜感激。

奇怪的具体问题,但这是一个有趣的问题,所以我尝试了一下。如果这是来自SQL数据库,我觉得更好的解决方案是让SQL为您格式化数据,而不是用ruby转换数据

@data = JSON.parse(request,symbolize_names: true)[:data]

intermediate = {}
@data.each do |row|
  time = row.delete(:time)
  row.each do |key, val|
    intermediate[key] ||= {data: {}}
    intermediate[key][:data][time] = val if val > 0
  end
end

transformed = []
intermediate.each do |key, val|
  transformed << {name: key.to_s, data: val}
end
@data=JSON.parse(请求,用符号表示_name:true)[:data]
中间={}
@数据。每个do |行|
时间=行。删除(:时间)
行。每个do |键,val|
中间[键]| |={数据:{}
中间[键][:数据][时间]=val如果val>0
结束
结束
转换=[]
中间。每个do |键,val|

转化了奇怪的特定问题,但这是一个有趣的问题,所以我尝试了一下。如果这是来自SQL数据库,我觉得更好的解决方案是让SQL为您格式化数据,而不是用ruby转换数据

@data = JSON.parse(request,symbolize_names: true)[:data]

intermediate = {}
@data.each do |row|
  time = row.delete(:time)
  row.each do |key, val|
    intermediate[key] ||= {data: {}}
    intermediate[key][:data][time] = val if val > 0
  end
end

transformed = []
intermediate.each do |key, val|
  transformed << {name: key.to_s, data: val}
end
@data=JSON.parse(请求,用符号表示_name:true)[:data]
中间={}
@数据。每个do |行|
时间=行。删除(:时间)
行。每个do |键,val|
中间[键]| |={数据:{}
中间[键][:数据][时间]=val如果val>0
结束
结束
转换=[]
中间。每个do |键,val|

transformed我同意csexton的观点,它看起来是一个更好的查询来获取数据,这将是最终的解决方案

无论如何,这里有一个类似于csexton的解决方案,但使用嵌套的默认哈希过程来简化一些操作:

def pivot(arr, column)
  results = Hash.new do |hash, key|
    hash[key] = Hash.new(0)
  end

  arr.each do |hash|
    data = hash.dup
    pivot = data.delete(column)

    data.each_pair do |name, value|
      results[name][pivot] += value
    end
  end

  results.map { |name, data| {
    name: name.to_s,
    data: data.delete_if { |_, sum| sum.zero? }
  }}
end

pivot(@data, :time) # => [{:name=>"A", :data=>{"2017-11-16"=>2, "2017-11-21"=>6}}, ..
这里有一个更“红宝石般”(取决于你问谁)的解决方案:

def pivot(arr, column)
  arr
    .flat_map do |hash|
      hash
        .to_a
        .delete_if { |key, _| key == column }
        .map! { |data| data << hash[column] }
    end
    .group_by(&:shift)
    .map { |name, outer| {
      name: name.to_s,
      data: outer
        .group_by(&:last)
        .transform_values! { |inner| inner.sum(&:first) }
        .delete_if { |_, sum| sum.zero? }
    }}
end

pivot(@data, :time) # => [{:name=>"A", :data=>{"2017-11-16"=>2, "2017-11-21"=>6}}, ..
def枢轴(arr,立柱)
啊
.flat_map do|hash|
搞砸
.给
.delete_如果{| key,124; key==column}
.地图!{| data{:name=>A,:data=>2017-11-16=>2,2017-11-21=>6}}。。

坦白地说,我觉得它很难阅读,我不想支持它。

我同意csexton的观点,它看起来是一个更好的查询,以获取数据将是这里的最终解决方案

无论如何,这里有一个类似于csexton的解决方案,但使用嵌套的默认哈希过程来简化一些操作:

def pivot(arr, column)
  results = Hash.new do |hash, key|
    hash[key] = Hash.new(0)
  end

  arr.each do |hash|
    data = hash.dup
    pivot = data.delete(column)

    data.each_pair do |name, value|
      results[name][pivot] += value
    end
  end

  results.map { |name, data| {
    name: name.to_s,
    data: data.delete_if { |_, sum| sum.zero? }
  }}
end

pivot(@data, :time) # => [{:name=>"A", :data=>{"2017-11-16"=>2, "2017-11-21"=>6}}, ..
这里有一个更“红宝石般”(取决于你问谁)的解决方案:

def pivot(arr, column)
  arr
    .flat_map do |hash|
      hash
        .to_a
        .delete_if { |key, _| key == column }
        .map! { |data| data << hash[column] }
    end
    .group_by(&:shift)
    .map { |name, outer| {
      name: name.to_s,
      data: outer
        .group_by(&:last)
        .transform_values! { |inner| inner.sum(&:first) }
        .delete_if { |_, sum| sum.zero? }
    }}
end

pivot(@data, :time) # => [{:name=>"A", :data=>{"2017-11-16"=>2, "2017-11-21"=>6}}, ..
def枢轴(arr,立柱)
啊
.flat_map do|hash|
搞砸
.给
.delete_如果{| key,124; key==column}
.map!{data}data[{:name=>A',:data=>2017-11-16=>2,2017-11-21=>6}}。。
坦率地说,我觉得它很难阅读,我不想支持它。:)

注意

arr.first.keys - [:time]
  #=> [:A, :B, :C, :D, :E]
注意

arr.first.keys - [:time]
  #=> [:A, :B, :C, :D, :E]