262 votes

Javascript reduce() sur un objet

Il existe une belle méthode Array reduce() pour obtenir une valeur du tableau. Exemple :

[0,1,2,3,4].reduce(function(previousValue, currentValue, index, array){
  return previousValue + currentValue;
});

Quelle est la meilleure façon d'obtenir la même chose avec des objets ? J'aimerais faire ceci :

{ 
    a: {value:1}, 
    b: {value:2}, 
    c: {value:3} 
}.reduce(function(previous, current, index, array){
  return previous.value + current.value;
});

Cependant, l'objet ne semble pas avoir reduce() méthode mise en œuvre.

328voto

Jonathan Lonowski Points 45253

Une option serait de reduce le site keys() :

var o = { 
    a: {value:1}, 
    b: {value:2}, 
    c: {value:3} 
};

Object.keys(o).reduce(function (previous, key) {
    return previous + o[key].value;
}, 0);

Avec cela, vous voudrez spécifier une valeur initiale ou le 1er tour sera 'a' + 2 .

Si vous voulez le résultat sous forme d'objet ( { value: ... } ), vous devrez initialiser et retourner l'objet à chaque fois :

Object.keys(o).reduce(function (previous, key) {
    previous.value += o[key].value;
    return previous;
}, { value: 0 });

138voto

Daniel Bayley Points 1304

Ce que vous voulez en fait dans ce cas, ce sont les Object.values . Voici un résumé ES6 en gardant cela à l'esprit :

const add = {
  a: {value:1},
  b: {value:2},
  c: {value:3}
}

const total = Object.values(add).reduce((t, {value}) => t + value, 0)

console.log(total) // 6

ou simplement :

const add = {
  a: 1,
  b: 2,
  c: 3
}

const total = Object.values(add).reduce((t, n) => t + n)

console.log(total) // 6

88voto

faboulaws Points 728

Mise en œuvre de l'ES6 : Objet.entries()

const o = {
  a: {value: 1},
  b: {value: 2},
  c: {value: 3}
};

const total = Object.entries(o).reduce(function (total, pair) {
  const [key, value] = pair;
  return total + value.value;
}, 0);

21voto

ZER0 Points 7358

Tout d'abord, vous ne comprenez pas vraiment ce que réduire le site de la valeur précédente.

Dans votre pseudo-code, vous avez return previous.value + current.value Par conséquent, la previous sera un nombre lors du prochain appel, et non un objet.

Deuxièmement, reduce est une méthode de tableau, et non d'objet, et vous ne pouvez pas vous fier à l'ordre lorsque vous itérez les propriétés d'un objet (voir : https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Statements/for...in ce qui est appliqué à Clé d'objet aussi) ; donc je ne suis pas sûr que l'application de reduce sur un objet a du sens.

Cependant, si l'ordre n'est pas important, vous pouvez avoir :

Object.keys(obj).reduce(function(sum, key) {
    return sum + obj[key].value;
}, 0);

Ou vous pouvez juste carte la valeur de l'objet :

Object.keys(obj).map(function(key) { return this[key].value }, obj).reduce(function (previous, current) {
    return previous + current;
});

P.S. en ES6 avec la syntaxe de la fonction fat arrow (déjà dans Firefox Nightly), vous pourriez rétrécir un peu :

Object.keys(obj).map(key => obj[key].value).reduce((previous, current) => previous + current);

6voto

Maik Lowrey Points 106

Permettez-moi de résumer les possibilités. Le but est toujours de faire un tableau à partir de l'objet. Il existe plusieurs fonctions Javascript pour les objets. Pour chaque fonction individuelle, il existe différentes façons de l'interpréter. Cela dépend donc toujours de l'aspect de notre objet et de ce que nous voulons faire.

Dans l'exemple ci-dessus, il s'agit d'un objet avec trois objets.

const obj = { 
    a: {value: 1}, 
    b: {value: 2}, 
    c: {value:3} 
};

Avec Object.keys

Object.keys ne nous donne que les clés de l'objet.

const arr = Object.keys(obj);
// output arr: 
[a, b, c]

const result = arr.reduce((total, key) => {
    return sum + obj[key].value;
}, 0);
// output result
// 6

Avec Object.value

Object.value() renvoie toutes les valeurs d'un tableau.

const arr = Object.value(obj);
// output arr
[
   {value: 1},
   {value: 2},
   {value: 3},
]

const result = arr.reduce((total, singleValue) => {
   return total + singleValue.value;
}, 0);

// output result
// 6

// Or the short variant
const resultShort = Object.values(obj).reduce((t, n) => t + n.value, 0)

// output resultShort
// 6

Avec Object.entries

Object.entries divise chaque valeur individuelle de l'objet en un tableau.

const arr = Object.entries(obj)
// output arr
[
  ["a", {visitors: 1}],
  ["b", {visitors: 2}],
  ["c", {visitors: 4}]
]

const result = arr.reduce((total, singleArr) => {
  return total + singleArr[1].value;
}, 0);

// output result
// 6

Que vous le fassiez avec reduce ou avec la fonction de tableau map() dépend de vous et de ce que vous voulez faire.

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