I want to create a real time-series array. Currently, I am using the statistics gem to pull out values for each 'day':
define_statistic :sent_count, :count
=> :all, :group => 'DATE(date_sent)',    
:filter_on => {:email_id => 'email_id
> = ?'}, :order => 'DATE(date_sent) ASC'
What this does is create an array where there are values for a date, for example
[["12-20-2010",1], ["12-24-2010",3]]
But I need it to fill in the null values, so it looks more like:
[["12-20-2010",1], ["12-21-2010",0], ["12-22-2010",0], ["12-23-开发者_开发知识库2010",0], ["12-24-2010",3]]
Notice how the second example has "0" values for the days that were missing from the first array.
#!/usr/bin/ruby1.8
require 'date'
require 'pp'
def add_missing_dates(series)
  series.map do |date, value|
    [Date.strptime(date, '%m-%d-%Y'), value]
  end.inject([]) do |series, date_and_value|
    filler = if series.empty?
               []
             else
               ((series.last[0]+ 1)..(date_and_value[0] - 1)).map do |date|
                 [date, 0]
               end
             end
    series + filler + [date_and_value]
  end.map do |date, value|
    [date.to_s, value]
  end
end
a = [["12-20-2010",1], ["12-24-2010",3]]
pp add_missing_dates(a)
# => [["2010-12-20", 1],
# =>  ["2010-12-21", 0],
# =>  ["2010-12-22", 0],
# =>  ["2010-12-23", 0],
# =>  ["2010-12-24", 3]]
I would recommend against monkey-patching the base classes to include this method: It's not all that general purpose; even if it were, it just doesn't need to be there. I'd stick it in a module that you can mix in to whatever code needs it:
module AddMissingDates
  def add_missing_dates(series)
    ...
  end
end
class MyClass
  include AddMissingDates
  ...
end
However, if you really want to:
def Array.add_missing_dates(series)
  ...
end
This works:
#!/usr/bin/env ruby
require 'pp'
require 'date'
# convert the MM-DD-YYYY format date string to a Date
DATE_FORMAT = '%m-%d-%Y'
def parse_date(s)
  Date.strptime(s, DATE_FORMAT)
end
dates = [["12-20-2010",1], ["12-24-2010",3]]
# build a hash of the known dates so we can skip the ones that already exist.
date_hash = Hash[*dates.map{ |i| [parse_date(i[0]), i[-1]] }.flatten]
start_date_range = parse_date(dates[0].first) 
end_date_range   = parse_date(dates[-1].first)
# loop over the date range...
start_date_range.upto(end_date_range) do |d|
  # ...and adding entries for the missing ones.
  date_hash[d] = 0 if (!date_hash.has_key?(d))
end
# convert the hash back into an array with all dates
all_dates = date_hash.keys.sort.map{ |d| [d.strftime(DATE_FORMAT), date_hash[d] ] }
pp all_dates
# >> [["12-20-2010", 1],
# >>  ["12-21-2010", 0],
# >>  ["12-22-2010", 0],
# >>  ["12-23-2010", 0],
# >>  ["12-24-2010", 3]]
Most of the code is preparing things, either to build a new array, or return the date objects back to strings.
 
         
                                         
                                         
                                         
                                        ![Interactive visualization of a graph in python [closed]](https://www.devze.com/res/2023/04-10/09/92d32fe8c0d22fb96bd6f6e8b7d1f457.gif) 
                                         
                                         
                                         
                                         加载中,请稍侯......
 加载中,请稍侯......
      
精彩评论