Media del conjunto de veces como cadenas en Ruby.

Tengo una matriz:

array = ["0:00:31", "0:00:52", "0:01:05", "0:00:55", "0:01:33", "0:00:05", "0:00:01", "0:05:10", "0:02:40", "0:03:03", "0:01:33", "0:00:00"] 

y necesito promediar todas las veces en la matriz que no son iguales a "0:00:00" . "0:00:00" debe ser expulsado.

¿Cuál es la mejor manera de hacer esto? Actualmente estoy haciendo un bucle a través de la matriz, eliminando todos los valores de 0:00:00 , convirtiendo las cadenas en enteros y haciendo un promedio. Pero parece mucho código para lo que estoy tratando de hacer.

 (sz = array.reject {|t| t == '0:00:00' }). map {|t| Time.parse t }. reduce(0) {|a, t| a += t.to_i }.to_f / sz.size 

Quieres agrupar estas cosas en operaciones funcionales. Rechaza las cosas que no necesitas, luego actúa sobre el rest.

Aquí, reduce es una forma viable de obtener un promedio de matriz, y se ha respondido antes.


Aquí hay una alternativa que es un poco más concisa, un poco más críptica.

 (sz = array.reject {|t| t == '0:00:00' }). map {|t| Time.parse(t).to_i }. reduce(:+).to_f / sz.size 

Ajustar la respuesta de NewAlexandria para devolver el promedio en segundos:

 (sz = array.reject {|t| t == '0:00:00' }). map {|t| t.split(":").inject(0){|product,n| product * 60 + n.to_i} }. reduce(0) {|a, t| a += t.to_i }.to_f / sz.size 

No estoy logrando que la respuesta de NewAlexandria funcione por alguna razón, así es como lo haría:

 def average_of_times(array) zero_seconds = ->x{ x=='0:00:00' } covert_to_seconds = ->x do hours, minutes, seconds = x.split(':').map(&:to_i) hours * 3600 + minutes * 60 + seconds end seconds = array.reject!(&zero_seconds) .map(&covert_to_seconds) .reduce(:+) / array.size Time.at(seconds).utc.strftime("%H:%M:%S") end