显示JSON中每个日期的所有值 [英] Display all the values for every date in JSON

查看:104
本文介绍了显示JSON中每个日期的所有值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下JSON:

{
    "groups" : [
      {
        "values": "21",
        "date": "2013-02-22"
      },
      {
        "values": "25",
        "date": "2013-02-22"
      },
      {
        "values": "20",
        "date": "2013-02-22"
      },
      {
        "values": "19",
        "date": "2013-02-22"
      },
      {
        "values": "42",
        "date": "2013-02-10"
      },
      {
        "values": "30",
        "date": "2013-02-10"
      },
      {
        "values": "11",
        "date": "2013-02-10"
      }

    ]
}

我已经在Ruby Class中提取了值和日期.我想找到每个日期的最高"和最低"值.我该怎么办?

I have the values and the date already extracted in a Ruby Class. I want to find the "highest" and "lowest" value for every date. How do I do that?

我也想为它创建并行数组.例如:

Also I want to create parallel arrays for the same. For instance:

low = [12, 22, 11, 45]
high = [34, 50, 15, 60]
dates = ["2013-02-22", "2013-02-10", "2013-02-06", "2013-02-01"]

我还想显示每个日期的所有值.

I would also like to display all the values for every date.

有人可以给我一些指导吗?

Could someone please give me some direction for this?

推荐答案

如果str是您的JSON字符串:

If str is your JSON string:

require 'json'
arr = JSON.parse(str)["groups"]
  #=> [{"values"=>"21", "date"=>"2013-02-22"},
  #    {"values"=>"25", "date"=>"2013-02-22"},
  #    {"values"=>"20", "date"=>"2013-02-22"},
  #    {"values"=>"19", "date"=>"2013-02-22"},
  #    {"values"=>"42", "date"=>"2013-02-10"},
  #    {"values"=>"30", "date"=>"2013-02-10"},
  #    {"values"=>"11", "date"=>"2013-02-10"}] 

by_date = arr.each_with_object(Hash.new {|h,k| h[k] = []}) { |g,h|
  h[g["date"]] << g["values"].to_i }
  # => {"2013-02-22"=>[21, 25, 20, 19], "2013-02-10"=>[42, 30, 11]}

dates = by_date.keys
  #=> ["2013-02-22", "2013-02-10"]     
min_vals, max_vals = *by_date.map { |_,vals| vals.minmax }
  #=> [[19, 25], [11, 42]] 
min_vals
  #=> [19, 25] 
max_vals
  #=> [11, 42] 

方法 Enumerable#each_with_object 需要一个参数,它是将由该方法构造并返回的对象的初始值.它的值由第二个块变量h给出.我将该参数设置为空散列,其默认值由该块提供:

The method Enumerable#each_with_object takes an argument that is the initial value of the object that will be constructed and returned by the method. It's value is given by the second block variable, h. I made that argument an empty hash with a default value given by the block:

{|h,k| h[k] = []}

什么是默认值"?这意味着如果哈希h没有键k,则h[k]返回一个空数组.让我们看看它是如何工作的.

What is the "default value"? All it means is that if the hash h does not have a key k, h[k] returns an empty array. Let's see how that works here.

h #=> {}each_with_object最初将第一个块变量g设置为等于arr的第一个值:

Initially, h #=> {} and each_with_object sets the first block variable, g equal to the first value of arr:

g = {"values"=>"21", "date"=>"2013-02-22"}

并执行块计算:

h[g["date"]] << g["values"].to_i
  #=> h["2013-02-22"] << 21

由于h没有键"2013-02-22",因此首先将h["2013-02-22"]设置为等于默认值的空数组:

Since h does not have a key "2013-02-22", h["2013-02-22"] is first set equal to the default value, an empty array:

h["2013-02-22"] = []

然后

h["2013-02-22"] << 21
  #=> [21] 
h #=> {"2013-02-22"=>[21]} 

arr的下一个值传递到块时:

When the next value of arr is passed to the block:

g = {"values"=>"25", "date"=>"2013-02-22"}

h如上所述.所以现在块计算为:

and h is as above. So now the block calculation is:

h[g["date"]] << g["values"].to_i
  #=> h["2013-02-22"] << 25
  #=> [21, 25] 
h #=> {"2013-02-22"=>[21, 25]} 

由于h具有键"2013-02-22",所以这次未使用默认值.

The default value is not used this time, as h has a key "2013-02-22".

另一件事可能需要解释:

One other thing may require explanation: the "splat" * in:

min_vals, max_vals = *by_date.map { |_,vals| vals.minmax }

我们看到了:

by_date.map { |date, vals| vals.minmax }
  #=> [[19, 25], [11, 42]]

如果*by_date.map { |date, vals| vals.minmax }位于等式的右侧,则使用splat会导致[[19, 25], [11, 42]]的两个元素使用 parallel分配分配给等式左侧的变量. splat运算符必须位于每一个最红宝石的花招.

If *by_date.map { |date, vals| vals.minmax } is on the right side of an equality, the splat causes the two elements of [[19, 25], [11, 42]] are assigned to variables on the left side of the equality using parallel assignment. The weird and wonderful splat operator needs to be in every Rubiest's bag of tricks.

由于我在块计算中没有使用date,因此我将其替换为局部变量_,从而引起了人们的注意.

Since I'm not using date in the block calculation, I've drawn attention to that by replacing date with the local variable _.

编辑:要回答您在评论中发布的问题,

To answer the question you posted in a comment, if:

id   = [1,1,1,2,2,3,4]
high = [100,100,100,90,90,100,100]
low  = [20,20,20,10,10,30,40]

并且我正确理解了您的问题,您可以先进行计算:

and I understand your question correctly, you could first compute:

indices = id.each_with_index.to_a.uniq(&:first).map(&:last)
  #=> [0, 3, 5, 6]

那么您想要的三个数组是:

Then the three arrays you want are:

id.values_at(*indices)
  #=> [1, 2, 3, 4] 
high.values_at(*indices)
  #=> [100, 90, 100, 100] 
low.values_at(*indices)
  #=> [20, 10, 30, 40] 

这篇关于显示JSON中每个日期的所有值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆