Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby 在JSON中显示每个日期的所有值_Ruby_Json_Haml - Fatal编程技术网

Ruby 在JSON中显示每个日期的所有值

Ruby 在JSON中显示每个日期的所有值,ruby,json,haml,Ruby,Json,Haml,我有以下JSON: { "groups" : [ { "values": "21", "date": "2013-02-22" }, { "values": "25", "date": "2013-02-22" }, { "values": "20", "date": "2013-02-22" }, {

我有以下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类中提取了值和日期。我想找到每个日期的“最高”和“最低”值。我该怎么做

此外,我还想为相同的对象创建并行阵列。例如:

low = [12, 22, 11, 45]
high = [34, 50, 15, 60]
dates = ["2013-02-22", "2013-02-10", "2013-02-06", "2013-02-01"]
我还想显示每个日期的所有值


有人能给我一些指导吗?

如果
str
是您的JSON字符串:

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] 
什么是“默认值”?这意味着如果散列
h
没有键
k
h[k]
返回一个空数组。让我们看看这是怎么回事

最初,
h#=>{}
每个带有_对象的
设置第一个块变量,
g
等于
arr
的第一个值:

g = {"values"=>"21", "date"=>"2013-02-22"}
并执行块计算:

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

h
如上所述。那么现在区块计算是:

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

by_date.map { |date, vals| vals.minmax }
  #=> [[19, 25], [11, 42]]
如果
*by_date.map{| date,vals | vals.minmax}
位于等式的右侧,则splat会使用并行赋值将
[[19,25],[11,42]
的两个元素赋值给等式左侧的变量。每一个红宝石的诡计中都需要有诡异和奇妙的东西

由于我没有在块计算中使用
date
,因此我通过将
date
替换为局部变量
\uu
来引起注意

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

id   = [1,1,1,2,2,3,4]
high = [100,100,100,90,90,100,100]
low  = [20,20,20,10,10,30,40]
我正确理解你的问题,你可以先计算:

indices = id.each_with_index.to_a.uniq(&:first).map(&:last)
  #=> [0, 3, 5, 6]
那么您需要的三个阵列是:

id.values_at(*indices)
  #=> [1, 2, 3, 4] 
high.values_at(*indices)
  #=> [100, 90, 100, 100] 
low.values_at(*indices)
  #=> [20, 10, 30, 40] 
您可以
:date
并遍历日期。然后在组中创建一个
:值的数组

然后使用获取正确的值和最终数组,以获取数组并分配给日期,低和高

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

dates, low, high = json[:groups].group_by { |g| g[:date] }.map do |date, grouped|
  values = grouped.map { |group| group[:values] }
  [date, *values.minmax]
end.transpose
# => => [["2013-02-22", "2013-02-10"], ["19", "11"], ["25", "42"]] 

dates
# => ["2013-02-22", "2013-02-10"]
low
# => ["19", "11"]
high
# => ["25", "42"]

你试过什么?这里的函数非常有用。欢迎使用堆栈溢出。为我们提供最少的输入数据、预期的输出以及重现您所看到的问题所需的最少代码非常重要。最后一部分,重现问题所需的最少代码帮助我们不要尝试所有可能的方法,而是关注如何解决问题。照目前情况看,您似乎还没有尝试过,也没有希望我们为您尝试,或者解释如何去做,这两种方法都不适用。当您在一个问题中给出一个示例时(通常是一件非常好的事情),重要的是输入是有效的Ruby对象。正如您所知,JSON对象是字符串,因此您需要添加单引号
'{…}'
,或者使用
%s[…]
或一个heredoc。此外,您应该将所有输入值分配给变量,以便在答案和注释中引用它们,而无需定义它们。例如,
str=
'{…}`。非常好。做得好。这正是我要发布的内容<代码>按日期。映射{k,v{[k,v.minmax]}。to_h
也很有用。Cary,谢谢你的回答。这真的很有帮助。如果我已经在json中有了高/低值,并且能够用它创建一个数组,该怎么办?比如说,我有,
high=[100100100,90,90100100]low=[20,20,20,10,10,30,40]
。我还有一组元素的标识符<代码>id=[1,1,1,2,2,3,4]。如何根据标识符拆分此文件?我希望结果是
high=[10090100100]low=[20,10,30,40]id=[1,2,3,4]
。您必须更具体一些。也许最好再发一个问题。卡里,我已经把上面的评论编辑得更具体了。你明白我的问题吗?我刚看到你的评论,但我必须离开。我今天晚些时候再谈。@CarySwoveland我明白这一点,但我相信一门语言的新手必须经常阅读文档,并尝试所有的方法来回答问题,看看会发生什么,并从中学习。
by_date.map { |date, vals| vals.minmax }
  #=> [[19, 25], [11, 42]]
id   = [1,1,1,2,2,3,4]
high = [100,100,100,90,90,100,100]
low  = [20,20,20,10,10,30,40]
indices = id.each_with_index.to_a.uniq(&:first).map(&:last)
  #=> [0, 3, 5, 6]
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 = {
  "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" }
  ]
}

dates, low, high = json[:groups].group_by { |g| g[:date] }.map do |date, grouped|
  values = grouped.map { |group| group[:values] }
  [date, *values.minmax]
end.transpose
# => => [["2013-02-22", "2013-02-10"], ["19", "11"], ["25", "42"]] 

dates
# => ["2013-02-22", "2013-02-10"]
low
# => ["19", "11"]
high
# => ["25", "42"]