user4602228
user4602228

Reputation:

javascript reduce sum array with undefined values

I have this simple array with numbers:

var arr = [100,200,undefined,450,300];

I would like to use reduce for quickly summing up the values in that array like so...

var total = arr.reduce( function( s, v ){ return s += v } );

In return I am getting NaN.

Is there any way to make reduce to sum values in array with undefined values? like a flag or something... Thanks!

Upvotes: 7

Views: 7009

Answers (4)

Nina Scholz
Nina Scholz

Reputation: 386560

You could use a default value for falsy values (undefined, null, 0, '', and some more) with a logical OR ||, like

v || 0

That means if v is a truthy value, than take that value, if not, then take zero.

var arr = [100, 200, undefined, 450, 300],
    total = arr.reduce(function (s, v) { return s + (v || 0); }, 0);

console.log(total);

BTW,

s += v
   ^ 

is not necessary, because you do not use s anymore in the function. The returned value is the new value for s in the next loop. The variables of the callback are independent and they have their own scope.


  • Based on the comments, you need to normalize the data, if various types of items are given, which are not wanted.

    • Filter unwanted parts,

      .filter(v => !isNaN(v))
      
    • convert wanted parts to the same type

      .map(Number)
      
  • Then you need a function for folding the data, to get only a singel value out of two values, like an addition.

    function add(a, b) {
        return a + b;
    }
    
  • This function is now used as callback for Array#reduce with an

    initialValue (Optional)

    Value to use as the first argument to the first call of the callback. If no initial value is supplied, the first element in the array will be used. Calling reduce() on an empty array without an initial value is an error.

    result = array
        .filter(v => !isNaN(v))
        .map(Number)
        .reduce(add, 0);
    

Upvotes: 15

Mamun
Mamun

Reputation: 68933

Try with filter():

var arr = [100,200,undefined,450,300];

var total = arr.filter(i=>i != undefined).reduce( function( s, v ){ 
    return s += v;
  }, 0);
  
console.log(total)

Upvotes: 1

Suresh Atta
Suresh Atta

Reputation: 121998

Just a ternary should do

var arr = [100, 200, undefined, 450, 300];

var total = arr.reduce(function(s, v) {
return v ? s += v : s += 0
});

console.log(total);

Upvotes: 2

synthet1c
synthet1c

Reputation: 6282

You could filter out the non numbers before you reduce your array.

This is not the most efficient way to reduce the list, but it is the most explicit where you are separating the functionality so you can easily follow the logic without needing to read through more complex logic.

var arr = [100,200,undefined,450,300,'string'];

var total = arr
  .filter(function(x) { return typeof(x) === 'number'}) // remove any non numbers
  .reduce(function( s, v ){ return s + Number(v) }, 0);
  
console.log(
  total
)

Upvotes: 3

Related Questions