Давайте представим, что у нас есть массив целых чисел:
var values = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11];
Среднее получается по следующей формуле
A = (1 / n) Σxi (с i = 1 до n) ... Итак: x1 / n + x2 / n + ... + xn / n
Мы делим текущее значение на количество значений и добавляем предыдущий результат к возвращаемому значению.
Подпись метода Reduce
reduce(callback[,default_previous_value])
Функция сокращения обратного вызова принимает следующие параметры:
- p : результат предыдущего расчета
- c : текущее значение (из текущего индекса)
- i : текущее значение индекса элемента массива
- a : текущий уменьшенный массив
Второй параметр Reduce является значением по умолчанию ... (Используется, если массив пуст ).
Таким образом, средний метод уменьшения будет:
var avg = values.reduce(function(p,c,i,a){return p + (c/a.length)},0);
Если вы предпочитаете, вы можете создать отдельную функцию
function average(p,c,i,a){return p + (c/a.length)};
function sum(p,c){return p + c)};
А затем просто обратитесь к сигнатуре метода обратного вызова
var avg = values.reduce(average,0);
var sum= values.reduce(sum,0);
Или увеличьте прототип Array напрямую ..
Array.prototype.sum = Array.prototype.sum || function (){
return this.reduce(function(p,c){return p+c},0);
};
Можно делить значение каждый раз, когда вызывается метод Reduce.
Array.prototype.avg = Array.prototype.avg || function () {
return this.reduce(function(p,c,i,a){return p+(c/a.length)},0);
};
Или даже лучше , используя ранее определенные Array.protoype.sum ()
метод, оптимизируй процесс моего вызова деления только один раз :)
Array.prototype.avg = Array.prototype.avg || function () {
return this.sum()/this.length;
};
Тогда на любом объекте Array области:
[2, 6].avg();// -> 4
[2, 6].sum();// -> 8
NB: пустой массив с возвращаемым желанием NaN является более правильным, чем 0, на мой взгляд, и может быть полезным в конкретных случаях использования.
var elmt = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
было бы намного приятнее.