2011-01-27 2 views
3

Я думаю, что метод Ruby's inject действительно опрятен для расчета сумм. Но если я должен вычислить среднее и использовать inject, я всегда в конечном итоге с чем-то вроде этого:Как рассчитать средние значения с использованием функции Ruby Inject

total_ranked_query_results = @results.count { |result| result.class == RankedQueryResult } 
@results.inject(0.0) { |sum, result| result.class == RankedResult ? sum + result.average_precision : sum }/total_ranked_query_results 

Так что в основном приходится повторять два раза, чтобы узнать, сколько RankedResults есть для того, чтобы вычислить среднее значение.

Есть ли лучший (рубический) способ избежать этого?

ответ

3

Либо сделать количество и сумму в одной и той же итерации:

tmp = @results.inject([0.0, 0]) { |sum, result| 
    if RankedResult === result 
     [sum.first + result.average_precision, sum.last+1] 
    else 
     sum 
    end 
} 
tmp.first/tmp.last 

Или первый фильтр коллекции:

tmp = @results.filter { |result| RankedResult === result } 
tmp.inject(0.0) { |sum, result| sum+result.avergage_precision }/tmp.length 
+1

В первом примере tmp.last вычисляется неправильно, он должен быть увеличен только когда результат RankedResult – Tonttu

+0

спасибо, исправлено :-) – arnaud576875

Смежные вопросы