暂时我的思路是:
时间跨度为2013-6-30
到2013-07-07
,有以下三条数据
[“2013-07-05”, 12], ["2013-07-01", 24], ["2013-06-30", 34]
问题是这边如何建立一个这样的一维数组 [34, 24, 0, 0, 0, 12, 0, 0]
现在是用 hash 转一下
def last_7_days_commit
records = @user.records.where(commit_date: Date.today-8..Date.today-1)
@last_7_days_commit = []
a = {}
if records.count == 0
@last_7_days_commit = Array.new(7) {|index| index = 0}
else
records.each do |record|
a.merge! record.commit_date => record.value
end
last_7_days.each do |day|
if a.has_key? day
@last_7_days_commit << a[day]
else
@last_7_days_commit << 0
end
end
end
end
Array 也好,或者时间对应数据的 Hash(Ruby 1.9 的 Hash 是按插入顺序排序的) 也好,缺失的值都是必须显示声明的,不管是 0 还是 空值 nil。
之前我写过一篇 Android 优亿市场数据采集分析系统概要 ,有个技巧是 统计数据存储和展示应该是分开的,特别是涉及到多维时有很多空值的情况。希望能对你有所帮助:)
Behold...
require 'Date'
def last_7_days_commit
data_set = [["2013-07-05", 12], ["2013-07-01", 24], ["2013-06-30", 34]].reverse
data_set_flatten = data_set.flatten!
start_date = "2013-06-30"
result = []
i = 0
7.times do
if data_set_flatten.include? (Date.parse(start_date) + i).to_s
result << data_set_flatten[data_set_flatten.index((Date.parse(start_date) + i).to_s) + 1]
else
result << 0
end
i += 1
end
puts result
end
last_7_days_commit
lol, hack the way out...
require 'date'
a = [["2013-07-05", 12], ["2013-07-01", 24], ["2013-06-30", 34]].map do |d, n|
[Date.parse(d), n]
end
min = a.map(&:first).min
data = Hash[a]
(min..(min + 7)).map{|d| data[d] || 0}
require 'time'
arr = [['2013-07-05', 12], ["2013-07-01", 24], ["2013-06-30", 34]]
h = {}
h.default = 0
arr.each{|x| h[Time.parse x[0]] = x[1] }
arr.clear
8.times{|i| arr << h[h.keys.min +86400*i] }
p arr
来个接近自然语言一点的,也是我之前做数据展示时用的技巧。
require 'date'
require 'active_support/all'
date_to_count_hash = Hash[ (Date.parse("2013-6-30")..Date.parse("2013-07-07")).to_a.map {|i| [i, 0] } ]
[["2013-07-05", 12], ["2013-07-01", 24], ["2013-06-30", 34]].each {|date_str, count| date_to_count_hash[Date.parse(date_str)] = count }
date_to_count_hash.map(&:last)