在过去7天内迭代完成日期

Har*_*M V 1 ruby ruby-on-rails date ruby-on-rails-4

我需要构建一个对象数组,以在图表上显示数据,该图表显示过去7天的数据.有时在数据库中将缺少7天记录中的某些记录,因此我需要显示记录并将值标记为0以在阵列中具有7个对象.

现在我有

[
  {
    "date": "2016-05-14",
    "amount": 6000
  },
  {
    "date": "2016-05-12",
    "amount": 12000
  }
]
Run Code Online (Sandbox Code Playgroud)

我想要的是

[
    {
        "date": "2016-05-14",
        "amount": 6000
    },
    {
        "date": "2016-05-13",
        "amount": 0
    },
    {
        "date": "2016-05-12",
        "amount": 12000
    },
    {
        "date": "2016-05-11",
        "amount": 0
    },
    {
        "date": "2016-05-10",
        "amount": 0
    },
    {
        "date": "2016-05-09",
        "amount": 0
    },
    {
        "date": "2016-05-09",
        "amount": 0
    }
]
Run Code Online (Sandbox Code Playgroud)

Ale*_*kin 6

ts = JSON.parse '[
{
  "date": "2016-05-14",
  "amount": 6000
},
{
  "date": "2016-05-12",
  "amount": 12000
}]' # support ruby < 2.2

((Date.today-6..Date.today).map do |d|
  [d.iso8601, {'amount' => 0, 'date' => d.iso8601 }]
end.to_h.merge ts.group_by { |e| e['date'] }).values.flatten
Run Code Online (Sandbox Code Playgroud)

在这里,我们首先构建映射到零值的请求天数的哈希值,然后将其与现有值的哈希值合并.后者优先:

[Date.today].map do |d|
  [d.iso8601, {'amount' => 0, 'date' => d.iso8601 }]
end.to_h
#? { '2016-05-16' => {'amount' => 0, 'date' => '2016-05-16' } }
Run Code Online (Sandbox Code Playgroud)

(在真正的哈希中有七个项目.)

Enumerable#group_by 产生相同的结构:

[ {'amount' => 42, 'date' => Date.today } ].group_by { |e| e['date'] }
#? { '2016-05-16' => [{'amount' => 42, 'date' => '2016-05-16' }] }
Run Code Online (Sandbox Code Playgroud)

作为最后一步,我们将后者合并到前者中,并通过获取values结果并将其展平来摆脱日期键.


使用Hash#default_proc:

hsh = Hash.new do |h, k|
  ts.detect do |e|
    e['date'] == k.iso8601
  end || { 'amount' => 0, 'date' => k.iso8601 }
end
(Date.today-6..Date.today).map { |d| hsh[d] }
Run Code Online (Sandbox Code Playgroud)