Calculate average number of days between datetimes in Ruby
ruby, ruby-on-rails, ruby-on-rails-4
Solution
I think you have an off-by-one problem. If you have `n` values in `dates` then you'll have `n-1` differences between consecutive pairs so your `avg` should be:
avg = difference.inject{ |sum, el| sum + el }.to_f / (arr.size - 1)
And your `inject` is just a long winded way of saying `inject(:+)` so you could say:
avg = difference.inject(:+).to_f / (arr.size - 1)
In any case, you could use `map` and `each_cons` to make it a bit nicer:
dates.map(&:to_date).each_cons(2).map { |d1, d2| d1 - d2 }.inject(:+) / (dates.length - 1)
First we can convert everything to dates in one pass with `map(&:to_date)` rather than converting every time we need a date instead of a string. Then the `each_cons(2)` iterates over the array in consecutive pairs (i.e. `[1,2,3,4]` is iterated as `[[1,2], [2,3], [3,4]]`). Then a simple `map` to get the differences between the pairs and `inject(:+)` to add them all up.
The above will leave you with a `Rational` but you can `to_f` or `to_i` that if you need a floating point or integer value.
Problem
I want to take a list of datetimes in Ruby and then calculate the number of days between them and then average those dates. Is this correct? Is there a shorter way to do this? ``` dates = ["2012-08-05 00:00:00 UTC", "2012-06-17 00:00:00 UTC", "2012-06-15 00:00:00 UTC", "2011-06-06 00:00:00 UTC"] difference = Array.new dates.each_with_index do |date, index| if index != 0 difference << date.to_date - dates[index - 1].to_date end end avg = difference.inject{ |sum, el| sum + el }.to_f / arr.size ``` And then would that output it in days format? You can give me a Rails version as well if you'd like as I'll be pulling the datetimes from a model field.