Tableau Somme et moyenne
J'ai des problèmes pour ajouter tous les éléments d'un tableau ainsi que pour les faire la moyenne. Comment ferais-je cela et l'implémenterais - je avec le code que j'ai actuellement? Les éléments sont censés être définis comme je l'ai ci-dessous.
<script type="text/javascript">
//<![CDATA[
var i;
var elmt = new Array();
elmt[0] = "0";
elmt[1] = "1";
elmt[2] = "2";
elmt[3] = "3";
elmt[4] = "4";
elmt[5] = "7";
elmt[6] = "8";
elmt[7] = "9";
elmt[8] = "10";
elmt[9] = "11";
// problem here
for (i = 9; i < 10; i++)
{
document.write("The sum of all the elements is: " + /* problem here */ + " The average of all the elements is: " + /* problem here */ + "<br/>");
}
//]]>
</script>
30 réponses
var sum = 0;
for( var i = 0; i < elmt.length; i++ ){
sum += parseInt( elmt[i], 10 ); //don't forget to add the base
}
var avg = sum/elmt.length;
document.write( "The sum of all the elements is: " + sum + " The average is: " + avg );
Il suffit de parcourir le tableau, puisque vos valeurs sont des chaînes, elles doivent d'abord être converties en entier. Et la moyenne est juste la somme des valeurs divisées par le nombre de valeurs.
Une solution que je considère plus élégante:
var sum, avg = 0;
// dividing by 0 will return Infinity
// arr must contain at least 1 element to use reduce
if (arr.length)
{
sum = arr.reduce(function(a, b) { return a + b; });
avg = sum / arr.length;
}
document.write("The sum is: " + sum + ". The average is: " + avg + "<br/>");
ES6
const average = arr => arr.reduce( ( p, c ) => p + c, 0 ) / arr.length;
const result = average( [ 4, 4, 5, 6, 6 ] ); // 5
console.log(result);
Généralement moyen en utilisant un-liner réduire est comme ceci
elements.reduce(function(sum, a,i,ar) { sum += a; return i==ar.length-1?(ar.length==0?0:sum/ar.length):sum},0);
Spécifiquement à la question posée
elements.reduce(function(sum, a,i,ar) { sum += parseFloat(a); return i==ar.length-1?(ar.length==0?0:sum/ar.length):sum},0);
Une version efficace est comme
elements.reduce(function(sum, a) { return sum + a },0)/(elements.length||1);
Comprendre le tableau Javascript réduire en 1 Minute http://www.airpair.com/javascript/javascript-array-reduce
Comme gotofritz l'a souligné semble tableau.réduire ignore les valeurs indéfinies. voici donc un correctif:
(function average(arr){var finalstate=arr.reduce(function(state,a) { state.sum+=a;state.count+=1; return state },{sum:0,count:0}); return finalstate.sum/finalstate.count})([2,,,6])
Imaginons que nous avons un tableau d'entiers comme ceci:
var values = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11];
, La moyenne est obtenue avec la formule suivante:
Un= (1/n)Σxi ( avec i = 1 à n ) ... Donc: x1/n + x2/n + ... + xn / n
Nous divisons la valeur actuelle par le nombre de valeurs et ajoutons le résultat précédent à la valeur renvoyée.
La signature de la méthode reduce est
reduce(callback[,default_previous_value])
La fonction de rappel reduce prend les mesures suivantes paramètres:
- p : Résultat du calcul précédent
- c : Valeur actuelle (à partir de l'index actuel)
- i : valeur d'index de l'élément de tableau actuel
- a : le tableau réduit actuel
Le deuxième paramètre de réduction est la valeur par défaut ... (Utilisé dans le cas où le tableau est vide ).
Donc, la méthode de réduction moyenne sera:
var avg = values.reduce(function(p,c,i,a){return p + (c/a.length)},0);
Si vous préférez, vous peut créer une fonction séparée
function average(p,c,i,a){return p + (c/a.length)};
function sum(p,c){return p + c)};
Puis référez-vous simplement à la signature de la méthode de rappel
var avg = values.reduce(average,0);
var sum= values.reduce(sum,0);
Ou augmenter le prototype de tableau directement..
Array.prototype.sum = Array.prototype.sum || function (){
return this.reduce(function(p,c){return p+c},0);
};
Il est possible de diviser la valeur chaque fois que la méthode reduce est appelée..
Array.prototype.avg = Array.prototype.avg || function () {
return this.reduce(function(p,c,i,a){return p+(c/a.length)},0);
};
Ou encore mieux , à l'aide de la défini précédemment Tableau.protoype.somme()
Méthode, optimiser le processus mon appel de la division une seule fois:)
Array.prototype.avg = Array.prototype.avg || function () {
return this.sum()/this.length;
};
Puis sur tout Objet tableau de la portée:
[2, 6].avg();// -> 4
[2, 6].sum();// -> 8
NB: un tableau vide avec renvoyer un souhait NaN est plus correct que 0 dans mon point de vue et peut être utile dans des cas d'utilisation spécifiques.
Pas le plus rapide, mais le plus court et en une ligne utilise map () & reduce ():
var average = [7,14,21].map(function(x,i,arr){return x/arr.length}).reduce(function(a,b){return a + b})
Vous pouvez aussi utiliser lodash, _.somme (tableau) et _.mean (array) dans la partie Math (ont également un autre personnel pratique).
_.sum([4, 2, 8, 6]);
// => 20
_.mean([4, 2, 8, 6]);
// => 5
J'utilise ces méthodes dans ma bibliothèque personnelle:
Array.prototype.sum = Array.prototype.sum || function() {
return this.reduce(function(sum, a) { return sum + Number(a) }, 0);
}
Array.prototype.average = Array.prototype.average || function() {
return this.sum() / (this.length || 1);
}
Modifier: Pour les utiliser, il suffit de demander au tableau sa somme ou sa moyenne, comme:
[1,2,3].sum() // = 6
[1,2,3].average() // = 2
Une façon sournoise de le faire même si cela nécessite l'utilisation de (le très détesté) eval ().
var sum = eval(elmt.join('+')), avg = sum / elmt.length;
document.write("The sum of all the elements is: " + sum + " The average of all the elements is: " + avg + "<br/>");
Je pensais juste poster ceci comme l'une de ces options "en dehors de la boîte". Vous ne savez jamais, la sournoise pourrait vous accorder (ou enlever) un point.
Dans ES6-prêt navigateurs ce polyfill peut être utile.
Math.sum = (...a) => Array.prototype.reduce.call(a,(a,b) => a+b)
Math.avg = (...a) => this.sum(...a)/a.length;
Vous pouvez partager la même méthode d'appel entre Math.sum
,Math.avg
et Math.max
, tels que
var maxOne = Math.max(1,2,3,4) // 4;
Vous pouvez utiliser les mathématiques.somme comme
var sumNum = Math.sum(1,2,3,4) // 10
, Ou si vous avez un tableau pour résumer,vous pouvez utiliser
var sumNum = Math.sum.apply(null,[1,2,3,4]) // 10
Tout comme
var maxOne = Math.max.apply(null,[1,2,3,4]) // 4
Voici un ajout rapide à l'objet" Math "en javascript pour y ajouter une commande" average"!!
Math.average = function(input) {
this.output = 0;
for (this.i = 0; this.i < input.length; this.i++) {
this.output+=Number(input[this.i]);
}
return this.output/input.length;
}
Ensuite, j'ai cet ajout à l'objet "Math" pour obtenir la somme!
Math.sum = function(input) {
this.output = 0;
for (this.i = 0; this.i < input.length; this.i++) {
this.output+=Number(input[this.i]);
}
return this.output;
}
Alors tout ce que vous faites est
alert(Math.sum([5,5,5])); //alerts “15”
alert(Math.average([10,0,5])); //alerts “5”
Et où je mets le tableau d'espace réservé, passez simplement votre variable (l'entrée si ce sont des nombres peut être une chaîne à cause de son analyse en un nombre!)
Calcul de la moyenne (Moyenne) en utilisant reduce et ES6:
const average = list => list.reduce((prev, curr) => prev + curr) / list.length;
const list = [0, 10, 20, 30]
average(list) // 15
Commencez par définir toutes les variables que nous prévoyons d'utiliser. Vous noterez que pour le tableau numbers
, j'utilise la notation littérale de []
par opposition à la méthode constructeur array()
. De plus, j'utilise une méthode plus courte pour définir plusieurs variables à 0.
var numbers = [], count = sum = avg = 0;
Ensuite, je remplis mon tableau de nombres vides avec les valeurs 0 à 11. C'est pour m'amener à votre point de départ original. Notez comment je pousse sur le tableau count++
. Cela pousse la valeur actuelle de count, puis il incrémente pour la prochaine fois.
while ( count < 12 )
numbers.push( count++ );
Enfin, j'effectue une fonction "pour chacun" des nombres dans le tableau numbers. Cette fonction va gérer un nombre à la fois, que j'identifie comme "n" dans le corps de la fonction.
numbers.forEach(function(n){
sum += n;
avg = sum / numbers.length;
});
À la fin, nous pouvons afficher à la fois la valeur sum
et la valeur avg
sur notre console afin de voir le résultat:
// Sum: 66, Avg: 5.5
console.log( 'Sum: ' + sum + ', Avg: ' + avg );
Voir en action en ligne à http://jsbin.com/unukoj/3/edit
Je m'appuie sur la réponse D'Abdennour TOUMI. voici les raisons pour lesquelles:
1. Je suis d'accord avec Brad, je ne pense pas que c'est une bonne idée d'élargir l'objet que nous n'avons pas créé.
2.) array.length
est exactement fiable en javascript, je préfère Array.reduce
car a=[1,3];a[1000]=5;
maintenant a.length
serait de retour 1001
.
function getAverage(arry){
// check if array
if(!(Object.prototype.toString.call(arry) === '[object Array]')){
return 0;
}
var sum = 0, count = 0;
sum = arry.reduce(function(previousValue, currentValue, index, array) {
if(isFinite(currentValue)){
count++;
return previousValue+ parseFloat(currentValue);
}
return previousValue;
}, sum);
return count ? sum / count : 0;
};
Sur les navigateurs à feuilles persistantes, vous pouvez utiliser les fonctions de flèche
avg = [1,2,3].reduce((a,b) => (a+b);
En L'exécutant 100 000 fois, la différence de temps entre l'approche For loop et reduce est négligeable.
s=Date.now();for(i=0;i<100000;i++){ n=[1,2,3]; a=n.reduce((a,b) => (a+b)) / n.length };
console.log("100k reduce took " + (Date.now()-s) + "ms.");
s=Date.now();for(i=0;i<100000;i++){n=[1,2,3]; nl=n.length; a=0; for(j=nl-1;j>0;j--){a=a+n[j];} a/nl };
console.log("100k for loop took " + (Date.now()-s) + "ms.");
s=Date.now();for(i=0;i<1000000;i++){n=[1,2,3]; nl=n.length; a=0; for(j=nl-1;j>0;j--){a=a+n[j];} a/nl };
console.log("1M for loop took " + (Date.now()-s) + "ms.");
s=Date.now();for(i=0;i<1000000;i++){ n=[1,2,3]; a=n.reduce((a,b) => (a+b)) / n.length };
console.log("1M reduce took " + (Date.now()-s) + "ms.");
/*
* RESULT on Chrome 51
* 100k reduce took 26ms.
* 100k for loop took 35ms.
* 10M for loop took 126ms.
* 10M reduce took 209ms.
*/
Définissez votre compteur de boucle for sur 0.... vous obtenez l'élément 9 et vous avez terminé comme vous l'avez maintenant. Les autres réponses sont les mathématiques de base. Utilisez une variable pour stocker votre somme (besoin de lancer les chaînes en ints), et diviser par la longueur de votre tableau.
Juste pour les coups de pied:
var elmt = [0, 1, 2,3, 4, 7, 8, 9, 10, 11], l = elmt.length, i = -1, sum = 0;
for (; ++i < l; sum += elmt[i])
;
document.body.appendChild(document.createTextNode('The sum of all the elements is: ' + sum + ' The average of all the elements is: ' + (sum / l)));
Array.prototype.avg=function(fn){
fn =fn || function(e,i){return e};
return (this.map(fn).reduce(function(a,b){return parseFloat(a)+parseFloat(b)},0) / this.length ) ;
};
Puis:
[ 1 , 2 , 3].avg() ; //-> OUT : 2
[{age:25},{age:26},{age:27}].avg(function(e){return e.age}); // OUT : 26
protected void Submit_Click(object sender, EventArgs e)
{
foreach (ComputerLabReservationList row in db.ComputerLabReservationLists)
{
if (row.LabNo == lblLabNo.Text && row.ReservationDate == StartCld.Text && row.StartEndTime == ddlstartendtime.Text)
{
// string display = "This time have been reserved by others. Please reserve again.";
// ClientScript.RegisterStartupScript(this.GetType(), "yourMessage", "alert('" + display + "');", true);
ScriptManager.RegisterStartupScript(this, this.GetType(),
"alert",
"alert('This time already booked by other. Please insert another time');window.location ='Computerlabs.aspx';",
true);
}
else
{
ComputerLabReservationList crl = new ComputerLabReservationList()
{
ResvId = lblreservationid.Text,
LabNo = lblLabNo.Text,
LecturerId = lblLecturerID.Text,
ReservationDate = StartCld.Text,
StartEndTime = ddlstartendtime.Text
};
db.ComputerLabReservationLists.InsertOnSubmit(crl);
db.SubmitChanges();
ScriptManager.RegisterStartupScript(this, this.GetType(),
"alert",
"alert('Your Reservation was sucessfully');window.location ='MyComputerReservation.aspx';",
true);
}
}
}
Je pense que nous pouvons faire comme
var k=elmt.reduce(function(a,b){return parseFloat(a+parseFloat(b));})
var avg=k/elmt.length;
console.log(avg);
J'utilise parseFloat deux fois parce que lorsque 1) vous ajoutez (a)9+b("1") alors que le résultat sera "91", mais nous voulons plus. j'ai donc utilisé parseFloat
2) Lorsque l'ajout de (A) 9 + parseFloat("1") se produit bien que le résultat soit " 10 " mais il sera dans la chaîne que nous ne voulons pas, encore une fois j'ai utilisé parseFloat.
J'espère que je suis clair. Les Suggestions sont les bienvenues
Voici ma façon recrue de simplement trouver l'avg. Espérons que cela aide quelqu'un.
function numAvg(num){
var total = 0;
for(var i = 0;i < num.length; i++) {
total+=num[i];
}
return total/num.length;
}
Voici votre one liner:
var average = arr.reduce((sum,item,index,arr)=>index !== arr.length-1?sum+item:sum+item/arr.length,0)
Je pense que cela peut être une solution directe pour calculer la moyenne avec une boucle et une fonction for.
var elmts = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11];
function average(arr) {
var total = 0;
for (var i = 0; i < arr.length; i++) {
total += arr[i];
}
console.log(Math.round(total/arr.length));
}
average(elmts);
Il semble y avoir un nombre infini de solutions pour cela, mais j'ai trouvé cela concis et élégant.
const numbers = [1,2,3,4];
const count = numbers.length;
const reducer = (adder, value) => (adder + value);
const average = numbers.map(x => x/count).reduce(reducer);
console.log(average); // 2.5
Ou plus consisely:
const numbers = [1,2,3,4];
const average = numbers.map(x => x/numbers.length).reduce((adder, value) => (adder + value));
console.log(average); // 2.5
Selon votre navigateur, vous devrez peut-être effectuer des appels de fonctions explicites car les fonctions fléchées ne sont pas prises en charge:
const r = function (adder, value) {
return adder + value;
};
const m = function (x) {
return x/count;
};
const average = numbers.map(m).reduce(r);
console.log(average); // 2.5
Ou:
const average1 = numbers
.map(function (x) {
return x/count;
})
.reduce(function (adder, value) {
return adder + value;
});
console.log(average1);
Si vous avez besoin de la moyenne et que vous pouvez ignorer l'exigence de calculer la somme, vous pouvez calculer la moyenne avec un seul appel de reduce:
// Assumes an array with only values that can be parsed to a Float
var reducer = function(cumulativeAverage, currentValue, currentIndex) {
// 1. multiply average by currentIndex to find cumulative sum of previous elements
// 2. add currentValue to get cumulative sum, including current element
// 3. divide by total number of elements, including current element (zero-based index + 1)
return (cumulativeAverage * currentIndex + parseFloat(currentValue))/(currentIndex + 1)
}
console.log([1, 2, 3, 4, 5, 6, 7, 8, 9, 10].reduce(reducer, 0)); // => 5.5
console.log([].reduce(reducer, 0)); // => 0
console.log([0].reduce(reducer, 0)); // => 0
console.log([].reduce(reducer, 0)); // => 0
console.log([,,,].reduce(reducer, 0)); // => 0
console.log([].reduce(reducer, 0)); // => 0
Si quelqu'un en a besoin, voici une moyenne récursive.
Dans le contexte de la question initiale, vous pouvez utiliser la moyenne récursive si vous autorisez l'utilisateur à insérer des valeurs supplémentaires et, sans encourir Le coût de la visite de chaque élément à nouveau, souhaitez "mettre à jour" la moyenne existante.
/**
* Computes the recursive average of an indefinite set
* @param {Iterable<number>} set iterable sequence to average
* @param {number} initAvg initial average value
* @param {number} initCount initial average count
*/
function average(set, initAvg, initCount) {
if (!set || !set[Symbol.iterator])
throw Error("must pass an iterable sequence");
let avg = initAvg || 0;
let avgCnt = initCount || 0;
for (let x of set) {
avgCnt += 1;
avg = avg * ((avgCnt - 1) / avgCnt) + x / avgCnt;
}
return avg; // or {avg: avg, count: avgCnt};
}
average([2, 4, 6]); //returns 4
average([4, 6], 2, 1); //returns 4
average([6], 3, 2); //returns 4
average({
*[Symbol.iterator]() {
yield 2; yield 4; yield 6;
}
}); //returns 4
Comment:
Cela fonctionne en maintenant la moyenne actuelle et le nombre d'éléments. Lorsqu'une nouvelle valeur doit être incluse, vous incrémentez le nombre de 1, Mettez à l'échelle l'existant moyenne par (count-1) / count
, et d'ajouter newValue / count
à la moyenne.
Avantages:
- vous ne additionnez pas tous les éléments, ce qui peut entraîner un grand nombre qui ne peut pas être stocké dans un flottant 64 bits.
- vous pouvez "mettre à jour" une moyenne existante si des valeurs supplémentaires sont disponibles.
- , vous pouvez effectuer une moyenne mobile sans connaître la longueur de la séquence.
Inconvénients:
- engage beaucoup plus de divisions
- pas infini-limité à Nombre.Articles MAX_SAFE_INTEGER sauf si vous employez
BigNumber
Moyenne du contenu HTML itens
Avec jQuery ou Javascript querySelector
vous avez un accès direct aux données formatées... Exemple:
<p>Elements for an average: <span class="m">2</span>, <span class="m">4</span>,
<span class="m">2</span>, <span class="m">3</span>.
</p>
Donc, avec jQuery vous avez
var A = $('.m')
.map(function(idx) { return parseInt($(this).html()) })
.get();
var AVG = A.reduce(function(a,b){return a+b}) / A5.length;
Voir d'autres 4 façons (!) pour accéder à itens et la moyenne: http://jsfiddle.net/4fLWB/
Var arr = [1,2,3,4,5]
function avg(arr){
var sum = 0;
for (var i = 0; i < arr.length; i++) {
sum += parseFloat(arr[i])
}
return sum / i;
}
Avg(arr) ======>>>> 3
Cela fonctionne avec des chaînes comme des nombres ou des nombres dans le tableau.
Je recommanderais D3 dans ce cas. Il est le plus lisible (et fournit 2 différents types de moyennes)
let d3 = require('d3');
let array = [1,2,3,4];
let sum = d3.sum(array); //10
let mean = d3.mean(array); //2.5
let median = d3.median(array);
J'avais exactement 10 éléments (comme dans l'exemple) donc j'ai fait:
( elmt[0] + elmt[1] + elmt[2] + elmt[3] + elmt[4] +
elmt[5] + elmt[6] + elmt[7] + elmt[8] + elmt[9] ) / 10