Среднее значение по рельсам - собирать только при значении <> 0 - PullRequest
2 голосов
/ 14 марта 2011

Я использую этот код для вычисления среднего некоторых чисел - обратите внимание, что столбец rankings сериализован и содержит хэш:

@reviews.collect{|review| review.rankings[label].to_i}.sum.to_f/@reviews.length if @reviews.length > 0

Недостаток этого кода заключается в следующем: если одиниз значений nil, среднее значение вычисляется так, как если бы оно существовало как ноль.В основном проблема в том, что знаменатель @reviews.length предполагает, что каждый отзыв имеет соответствующее значение.

Как исключить из знаменателя те отзывы, которые не учитываются?


Спасибоочень за ваши ответы.Проблема оказалась в знаменателе, то есть в части /@reviews.length.Когда я использовал reject как для числителя, так и для знаменателя, уравнение перестало делиться на общую длину и начало делиться на (длина - нет нуля).

Конечный результат - 2 балла [0 и 100] в среднем до 50;[ноль и 100] в среднем до 100.

Ответы [ 3 ]

1 голос
/ 14 марта 2011

Я бы пошел с таким подходом (используя compact, чтобы убить nil с):

rankings = @reviews.map{ |review| review.rankings[label] }.compact
rankings.map(&:to_i).sum.to_f / rankings.count unless rankings.count == 0
1 голос
/ 14 марта 2011
  if @reviews.length > 0
   @reviews.collect{|r| r.rankings[label]}.compact.map(&:to_f).sum / @reviews.length
  else
   0
  end
1 голос
/ 14 марта 2011

Array#reject на помощь.

@reviews.reject{|review| review.rankings[label].nil?}.collect{|review| review.rankings[label].to_i}.sum.to_f/@reviews.length if @reviews.length > 0
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...