【问题标题】:Rails date range JSON dataRails 日期范围 JSON 数据
【发布时间】:2016-08-31 06:04:08
【问题描述】:

我希望有一个从 1.month.ago..Date.today 开始的日期范围,然后为每一天选择最高温度(因此应该得到 30 个单独的数字),然后总结结果。

我以 JSON 格式获取数据,其结构如下

{"status": "ok", "data": [{"temperature": 22.4, "date": "20160815-0345"}}

我通过循环解析数据。

@data['data'].each do |d|
 maxTotal << [DateTime.parse(d['date']), d['temperature']]
end

但是对于如何选择每天的最大值然后总结起来还不够。

@total = maxTotal { |a| a[0].to_date == (1.month.ago.to_date) }.max { |a,b| a[1] <=> b[1] }.sum[1]

【问题讨论】:

    标签: ruby-on-rails json ruby-on-rails-3.2


    【解决方案1】:

    更新:测试和工作

    json_data = @data['data']
    sum_of_max_temperature_in_each_day = json_data.
      group_by{ |h| Date.parse(h[:date]) }.
      reject{ |k, v| !( ((30.days.ago.to_date)..(Date.today)) === k ) }.
      inject(0){ |sum, h| sum + h.second.max_by{ |h| h[:temperature] }[:temperature] }
    

    解释(分解)

    # Example; let json_data be
    json_data = [
      {"temperature": 22.4, "date": "20160815-0345"},
      {"temperature": 10.4, "date": "20160815-1435"},
      {"temperature": 15.8, "date": "20990101-0430"},
      {"temperature": 4, "date": "20160816-0101"}
    ]
    
    # sum of max temperature each day within last 30 days
    puts json_data.
      group_by{ |h| Date.parse(h[:date]) }.
      reject{ |k, v| !( ((30.days.ago.to_date)..(Date.today)) === k ) }.
      inject(0){ |sum, h| sum + h.second.max_by{ |h| h[:temperature] }[:temperature] }
    => 26.4
    
    # 1) Group by day
    puts json_data.
      group_by{|h| Date.parse( h[:date] )}
    {
      Mon, 15 Aug 2016=>[
        {:temperature=>22.4, :date=>"20160815-0345"},
        {:temperature=>10.4, :date=>"20160815-1435"}
      ],
      Thu, 01 Jan 2099=>[
        {:temperature=>15.8, :date=>"20990101-0430"}
      ],
      Tue, 16 Aug 2016=>[
        {:temperature=>4, :date=>"20160816-0101"}
      ]
    }
    
    # 2) Remove those not within the last 30 days
    puts json_data.
      group_by{ |h| Date.parse(h[:date]) }.
      reject{ |k, v| !( ((30.days.ago.to_date)..(Date.today)) === k ) }
    
    {
      Mon, 15 Aug 2016=>[
       {:temperature=>22.4, :date=>"20160815-0345"},
       {:temperature=>10.4, :date=>"20160815-1435"}
      ],
      Tue, 16 Aug 2016=>[
        {:temperature=>4, :date=>"20160816-0101"}
      ]
    }
    
    # 3) Showing what's happening inside the inject() block.
    puts json_data.
      group_by{ |h| Date.parse(h[:date]) }.
      reject{ |k, v| !( ((30.days.ago.to_date)..(Date.today)) === k ) }.
      inject(0){ |sum, h| 
        puts "h ==> #{h}";
        puts "h.second ==> #{h.second}";
        puts "h.second.max_by ==> #{h.second.max_by{ |h| h[:temperature] }[:temperature]}"
      }
    
    h ==> [
      Mon, 15 Aug 2016,
      [
        {:temperature=>22.4, :date=>"20160815-0345"},
        {:temperature=>10.4, :date=>"20160815-1435"}
      ]
    ]
    h.second ==> [
      {:temperature=>22.4, :date=>"20160815-0345"},
      {:temperature=>10.4, :date=>"20160815-1435"}
    ]
    h.second.max_by ==> 22.4
    h ==> [
      Tue, 16 Aug 2016, 
      [
        {:temperature=>4, :date=>"20160816-0101"}
      ]
    ]
    h.second ==> [
      {:temperature=>4, :date=>"20160816-0101"}
    ]
    h.second.max_by ==> 4
    

    【讨论】:

    • 谢谢 Jay,你能解释一下 h.second.max_by 中 second 的用法吗?这似乎是当天的第二个记录,而不是最大记录。
    • @DollarChills 哦,不,.second 指的是变量h 的第二个,其中h 是一个大小为2 的数组,从上面可以看到。你会注意到h.first是Key,h.second是对应的Value。这是因为 inject() 循环遍历散列中的每个键值对(请参阅上面的第 2 部分散列),然后 h 变成类似于 [key, value] 的数组而不是散列 {key: value}。这就是为什么h.second 再次引用键指向的值(键是日期,值是:温度和:日期的哈希数组;见上文)希望这有帮助
    • 感谢您的解释。似乎工作得很好。非常感谢您的帮助!
    • @DollarChills 不用担心。很高兴能帮上忙:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多