I have the following method in my Array
class:
class Array
def avg
if partial_include?(":")
avg_times
else
blank? and 0.0 or (sum.to_f/size).round(2)
end
end
def avg_times
avg_minutes = self.map do |x|
hour, minute = x.split(':')
total_minutes = hour.to_i * 60 + minute.to_i
end.inject(:+)/size
"#{avg_minutes/60}:#{avg_minutes%60}"
end
def partial_include?(search_term)
self.each do |e|
return true if e[search_term]
end
return false
end
end
This works great with arrays of regular numbers, but there could instances where I have an array of times.
For example: [18:35, 19:07, 23:09]
Anyway to figure out the average of an array of time objects?
So you need do define a function that can calculate the average of times formatted as strings. Convert the data to minutes, avg the total minutes and then back to a time.
I would do it something like this:
a = ['18:35', '19:07', '23:09']
def avg_of_times(array_of_time)
size = array_of_time.size
avg_minutes = array_of_time.map do |x|
hour, minute = x.split(':')
total_minutes = hour.to_i * 60 + minute.to_i
end.inject(:+)/size
"#{avg_minutes/60}:#{avg_minutes%60}"
end
p avg_of_times(a) # = > "20:17"
Then when you call you function you check if any/all items in your array is formatted as a time. Maybe using regexp.
Here's a simple method that we're using:
def calculate_average_of_times( times )
hours = times.collect{ |time| time.split( ":" ).first.to_i } # Large Arrays should only
minutes = times.collect{ |time| time.split( ":" ).second.to_i } # call .split 1 time.
average_hours = hours.sum / hours.size
average_minutes = ( minutes.sum / minutes.size ).to_s.rjust( 2, '0' ) # Pad with leading zero if necessary.
"#{ average_hours }:#{ average_minutes }"
end
And to show it working with your provided Array
of 24-hour times, converted to Strings
:
calculate_average_of_times( ["18:35", "19:07", "23:09"] )
#=> "20:17"
Thanks to @matt-privman for the help and inspiration on this.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With