Reputation:
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
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. Callingreduce()
on an empty array without an initial value is an error.
result = array
.filter(v => !isNaN(v))
.map(Number)
.reduce(add, 0);
Upvotes: 15
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
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
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