383 votes

Javascript réduit sur un tableau d'objets

Dites que je veux additionner a.x pour chaque élément en arr .

 arr = [{x:1},{x:2},{x:4}]
arr.reduce(function(a,b){return a.x + b.x})
>> NaN
 

J'ai des raisons de croire que hache n'est pas défini à un moment donné.

Ce qui suit fonctionne bien

 arr = [1,2,4]
arr.reduce(function(a,b){return a + b})
>> 7
 

Qu'est-ce que je fais mal dans le premier exemple?

477voto

Casey Chu Points 8804

Un moyen plus propre pour y parvenir est de fournir une valeur initiale :

La première fois la fonction anonyme est appelée, elle est appelée avec et retourne . La prochaine fois, elle est appelée avec et retourne . Elle est ensuite appelée avec , enfin de retour .

412voto

JaredMcAteer Points 5936

Après la première itération votre êtes de retour d'un nombre et d'essayer d'en obtenir la propriété x à ajouter à l'objet suivant qui est - undefined - mathématiques impliquant undefined résultats en NaN.

essayer de retourner un objet contient un x de la propriété avec la somme des x propriétés de paramètres:

var arr = [{x:1},{x:2},{x:4}];

arr.reduce(function (a, b) {
  return {x: a.x + b.x}; // returns object with property x
})

Explication ajouté des commentaires:

La valeur de retour de chaque itération de l' [].reduce utilisé comme l' a variable dans la prochaine itération.

Itération 1: a = {x:1}, b = {x:2}, {x: 3} attribué a dans l'Itération 2

Itération 2: a = {x:3}, b = {x:4}.

Le problème avec votre exemple est que vous êtes de retour d'un nombre littéral.

function (a, b) {
  return a.x + b.x; // returns number literal
}

Itération 1: a = {x:1}, b = {x:2}, // returns 3 comme a dans la prochaine itération

Itération 2: a = 3, b = {x:2} retours NaN

Un nombre littéral 3 n'est pas (en général) ont une propriété appelée x donc undefined et undefined + b.x retours NaN et NaN + <anything> toujours NaN

39voto

RHSeeger Points 9217

D'autres ont répondu à cette question, mais je pensais avoir recours à une autre approche. Plutôt que d’aller directement à l’axe de sommation, vous pouvez combiner une carte (d’axe à x) et réduire (pour ajouter les x):

 arr = [{x:1},{x:2},{x:4}]
arr.map(function(a) {return a.x;})
   .reduce(function(a,b) {return a + b;});
 

Certes, cela sera probablement un peu plus lent, mais j’ai pensé que cela valait la peine de le mentionner comme option.

4voto

Jamie Wong Points 10858

À chaque étape de votre réduction, vous ne retournez pas un nouvel objet {x:???} . Donc, soit vous devez faire:

 arr = [{x:1},{x:2},{x:4}]
arr.reduce(function(a,b){return a + b.x})
 

ou vous avez besoin de faire

 arr = [{x:1},{x:2},{x:4}]
arr.reduce(function(a,b){return {x: a.x + b.x}; }) 
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X