2

I just learned javascript. Why is the return value NaN?

var arr = [
    { name: "A", quantity: 1, price: 20 },
    { name: "B", quantity: 2, price: 40 },
    { name: "C", quantity: 3, price: 60 },
    { name: "D", quantity: 4, price: 80 }
];
var test = arr.reduce(function(item1, item2){
    return (item1.quantity * item1.price) + (item2.quantity * item2.price);
});
console.log(test);
jkdev
  • 11,360
  • 15
  • 54
  • 77
Nhật An
  • 29
  • 2
  • reduce is an aggregator function which takes an initial value and then mutate it according to each entry in the array, which is not reflected in your code. What exactly are you trying to achieve – Umair Abid Mar 28 '19 at 04:48

3 Answers3

5

From the Array.reduce() documentation:

The reducer function takes four arguments:

  • Accumulator (acc)
  • Current Value (cur)
  • Current Index (idx)
  • Source Array (src)

Your reducer function's returned value is assigned to the accumulator, whose value is remembered across each iteration throughout the array and ultimately becomes the final, single resulting value.

So, I believe you wanted to do this instead:

var arr = [
  { name: "A", quantity: 1, price: 20 },
  { name: "B", quantity: 2, price: 40 },
  { name: "C", quantity: 3, price: 60 },
  { name: "D", quantity: 4, price: 80 }
];

var test = arr.reduce(function(acc, curr)
{
    return acc + (curr.quantity * curr.price);
}, 0);

console.log(test);
.as-console {background-color:black !important; color:lime;}
.as-console-wrapper {max-height:100% !important; top:0;}

Note, it is always good to explicitly define the initial value of the accumulator (0 in this particular case). Even if it is optional, won't work for this case:

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.

Why you get NaN?

Since you don't explicitly define the initial value of the accumulator, it will be the first object on the array:

{name: "A", quantity: 1, price: 20}

Now, the first iteration of the reduce() will work because the accumulator (named as item1 in your example) is an object and have the properties quantity and price. Even more, this iteration will return 1 * 20 + 2 * 40 = 100 and this will be the new value of the accumulator (item1). Now, second and later iterations of the reduce() won't work as you expect because the new value of the accumulator (after first iteration) is not an object and won't have the properties quantity and price. So, this latest issue will result on getting NaN as final value.

Shidersz
  • 16,846
  • 2
  • 23
  • 48
2

Based on a hunch that what you might need, does that solution produces right result for you? What it does is it initialises the output with 0 and then for each item in array it adds the value of (quantity * price) to output

var arr = [
{ name: "A", quantity: 1, price: 20 },
{ name: "B", quantity: 2, price: 40 },
{ name: "C", quantity: 3, price: 60 },
{ name: "D", quantity: 4, price: 80 }
];
var test = arr.reduce(function(acc, item){
    return acc + (item.quantity * item.price);
}, 0);
console.log(test); //600
Umair Abid
  • 1,453
  • 2
  • 18
  • 35
0

Why is the return value NaN? View here visual execution

First, you need to understand how the code is executing

enter image description here

Array.reduce() is a function which returns a new array and also it reduces the array from many values to one.

enter image description here

enter image description here

Manjeet Thakur
  • 2,288
  • 1
  • 16
  • 35