How to use the reduce (reduce) operation on objects?

Asked

Viewed 1,186 times

4

In Javascript, when I need to do a reduction operation, I use the method Array.reduce.

Thus:

var valores = [1, 2, 3, 4, 5, 1000];

var resultado = valores.reduce(function (soma, atual) {
    return soma + atual;
})

console.log(resultado);

But when I try to do it with a Array of objects, it doesn’t work very well:

var valores = [{valor: 1}, {valor: 2}, {valor: 3}, {valor: 4}, {valor: 5}, {valor: 1000}];


var resultado = valores.reduce(function (soma, atual) {
        return soma.valor + atual.valor;
})

console.log(resultado);

In this case, returns NaN.

But I wish I could apply the reduction operation on an object in a certain specific attribute.

How to do this in Javascript?

  • 1

    by what seems the objects that are read first are the valor1 and valor2, after that the first value soma begins to be undefined. put a console.log in place of the reduce and you will see.

  • 1

    Related: https://answall.com/q/161754/101 Also: https://answall.com/q/195126/101

5 answers

6


In your first example you are not passing the initial value of the sum, you should do that, is the second argument of .reduce(fn, valorInicial). This part is the same in the two examples.

The difference for an object array is just passing the property that has the number you need.

Would look like this:

var valores = [{valor: 1}, {valor: 2}, {valor: 3}, {valor: 4}, {valor: 5}, {valor: 1000}];
var resultado = valores.reduce(function(soma, atual) {
  return soma + atual.valor;
}, 0)

console.log(resultado);

In ES6 it would be:

var valores = [{valor: 1}, {valor: 2}, {valor: 3}, {valor: 4}, {valor: 5}, {valor: 1000}];
var resultado = valores.reduce(
    (soma, atual) => soma + atual.valor, 0
);

console.log(resultado);

5

The first parameter will accumulate the sum, an option for your case is also to indicate the initialization:

const valores = [{valor: 1}, {valor: 2}, {valor: 3}, {valor: 4}, {valor: 5}, {valor: 1000}];

const resultado = valores.reduce((a, b) => a + b.valor, 0);

console.log(resultado);

  • 2

    +1 I had implemented the way I answered here in my system, but I ended up using this :D

5

You forgot to pass the second parameter to the reduce function, which is the value that will start the operation, see:

var valores = [{valor: 1}, {valor: 2}, {valor: 3}, {valor: 4}, {valor: 5}, {valor: 1000}];

var resultado = valores.reduce(function (soma, atual) {
    return soma + atual.valor;
}, 0) // Inicia o valor de soma com 0

console.log(resultado); // 1015

3

It is necessary, first of all, to understand that in function reduce the return of each execution/iteration will be used as the first parameter in the next iteration.

In the question code a number is returned in the first iteration and in the next is trying to access the property valor of this number.

You can return a new object that contains the value property and make it work the way you expect it to.

var valores = [{valor: 1}, {valor: 2}, {valor: 3}, {valor: 4}, {valor: 5}, {valor: 1000}];

var resultado = valores.reduce(function (soma, atual) {
  return { valor: soma.valor + atual.valor };
})

console.log(resultado);

You can also set an initial value for the sums

var valores = [{valor: 1}, {valor: 2}, {valor: 3}, {valor: 4}, {valor: 5}, {valor: 1000}];
    
var resultado = valores.reduce((soma, obj) => soma + obj.valor, 0);

console.log(resultado);

  • Interesting, I would have solved it differently, but this one was sensational.

2

I’ll give you my toothpick too. Just use the Object.keys to list object keys.

var valores = [{valor: 1}, {valor: 2}, {valor: 3}, {valor: 4}, {valor: 5}, {valor: 1000}];

var resultado = Object.keys(valores).reduce(function (soma, key) {
    return soma + valores[key].valor;
}, 0)

console.log(resultado);

In my case, it only gave the expected result when I added the initial value, defined in the second parameter of reduce, with the 0.

  • 2

    It can be useful too, especially if the use of the keys is more complex within the function, but as it has a step before it only gets a little slower :p

Browser other questions tagged

You are not signed in. Login or sign up in order to post.