Vamos imaginar que temos uma matriz de números inteiros como este:
var values = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11];
A média é obtida com a seguinte fórmula
A = (1 / n) Σxi (com i = 1 para n) ... Então: x1 / n + x2 / n + ... + xn / n
Dividimos o valor atual pelo número de valores e adicionamos o resultado anterior ao valor retornado.
A assinatura do método de redução é
reduce(callback[,default_previous_value])
A função de redução de retorno de chamada utiliza os seguintes parâmetros:
- p : Resultado do cálculo anterior
- c : valor atual (do índice atual)
- i : Valor do índice do elemento da matriz atual
- a : A matriz reduzida atual
O segundo parâmetro de redução é o valor padrão ... (Usado no caso de a matriz estar vazia ).
Portanto, o método de redução média será:
var avg = values.reduce(function(p,c,i,a){return p + (c/a.length)},0);
Se preferir, você pode criar uma função separada
function average(p,c,i,a){return p + (c/a.length)};
function sum(p,c){return p + c)};
E, em seguida, basta consultar a assinatura do método de retorno de chamada
var avg = values.reduce(average,0);
var sum= values.reduce(sum,0);
Ou aumente o protótipo da matriz diretamente.
Array.prototype.sum = Array.prototype.sum || function (){
return this.reduce(function(p,c){return p+c},0);
};
É possível dividir o valor cada vez que o método de redução é chamado.
Array.prototype.avg = Array.prototype.avg || function () {
return this.reduce(function(p,c,i,a){return p+(c/a.length)},0);
};
Ou melhor ainda , usando o Array.protoype.sum () definido anteriormente
método, otimizar o processo chamando a divisão apenas uma vez :)
Array.prototype.avg = Array.prototype.avg || function () {
return this.sum()/this.length;
};
Então, em qualquer objeto Array do escopo:
[2, 6].avg();// -> 4
[2, 6].sum();// -> 8
Nota: um array vazio com retorno de um desejo NaN é mais correto que 0 no meu ponto de vista e pode ser útil em casos de uso específicos.
var elmt = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
seria muito melhor.