新手问题 数据处理

vincent178 · 2013年07月07日 · 最后由 mvj3 回复于 2013年07月09日 · 3015 次阅读

需求是,我要建立一个图表来展示一周的数据

暂时我的思路是: 时间跨度为2013-6-302013-07-07,有以下三条数据

[“2013-07-05”, 12], ["2013-07-01", 24], ["2013-06-30", 34]

问题是这边如何建立一个这样的一维数组 [34, 24, 0, 0, 0, 12, 0, 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

第一感是用全 1 mask 与运算 或者全 nil 或运算…… 出门在外无法测试,脑补应该能成

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}

#5 楼 @luikore 给跪了... 不用 Hash 能怎么写...

#5 楼 @luikore 大师,收我为徒吧。。。

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)
需要 登录 后方可回复, 如果你还没有账号请 注册新账号