Reduce Method Question

Hello, I have a question about the reduce method, and why these two snippets achieve the same result, but have slightly different code.

My goal is to get the sum of every inventors age, which I have done but I am not sure which way is more correct!

Array:

const inventors = [
  { first: 'Albert', last: 'Einstein', year: 1879, passed: 1955 },
  { first: 'Isaac', last: 'Newton', year: 1643, passed: 1727 },
  { first: 'Galileo', last: 'Galilei', year: 1564, passed: 1642 },
  { first: 'Marie', last: 'Curie', year: 1867, passed: 1934 },
  { first: 'Johannes', last: 'Kepler', year: 1571, passed: 1630 },
  { first: 'Nicolaus', last: 'Copernicus', year: 1473, passed: 1543 },
  { first: 'Max', last: 'Planck', year: 1858, passed: 1947 },
  { first: 'Katherine', last: 'Blodgett', year: 1898, passed: 1979 },
  { first: 'Ada', last: 'Lovelace', year: 1815, passed: 1852 },
  { first: 'Sarah E.', last: 'Goode', year: 1855, passed: 1905 },
  { first: 'Lise', last: 'Meitner', year: 1878, passed: 1968 },
  { first: 'Hanna', last: 'Hammarström', year: 1829, passed: 1909 },
];

MDN Docs does something like this:

const inventorsYears = inventors.reduce((total, inventor) => {
  return total + (inventor.passed - inventor.year);
}, 0);
console.log(inventorsYears);

I guess I am having a hard time understanding what the 0 after the }, actually does. I know that it sets the total to 0, but how?

I did something like this, just setting the total to 0, right before the return statement. Is this incorrect or a bad practice? I’m getting the same result.

const inventorsYears = inventors.reduce((total, inventor) => {
  total = 0;
  return total + (inventor.passed - inventor.year);
});
console.log(inventorsYears);

Those give you the same result? For me they give very different results. The first one gives me the correct answer of 861 and the second gives me 80, the age of the last one checked.

The issue is this: total = 0;

That is supposed to be a running total, but you are resetting it to 0 on each iteration. So for each inventor, the running total starts over at 0. That won’t work.

The reduce method is a confusing method to a lot of people. I even had to explain it to a senior dev once.

Would this help you visualize what is happening in the first version?

const reduceByAge = (total, inventor) => total + (inventor.passed - inventor.year)
const STARTING_TOTAL = 0

const inventorsYears = inventors.reduce(reduceByAge, STARTING_TOTAL)

console.log(inventorsYears)

To the reduce method we first pass a callback and then a starting total.

In the reduceByAge callback just takes in a total and the current iteration element (“inventor”). It returns the new total after the current age is added. This is what we expect, this is how reduce works.

The second parameter we passed (“STARTING_TOTAL”) is the starting point. Since we are summing, we want 0. In some cases you can omit this - if the starting value is undefined, reduce will just use the first element to start and start iterating with the second element. But that won’t work in this case since our elements were objects. If our array was an array of ages, that could work. (We could map over the array to make an array of ages, but I think that is more trouble than it is worth.)

Does that help?

My old motto is, “When in doubt, log it out!”. Try this version of the callback:

const reduceByAge = (total, inventor, i) => {
  console.log(`i=${i} current running total is ${total} and inventor is ${JSON.stringify(inventor)}`)
  console.log('returning new total,', total + (inventor.passed - inventor.year))
  return total + (inventor.passed - inventor.year)
}
1 Like

Hey Kevin,

Thank you so much for that! I think when I was running it, my browser didn’t automatically reload, so I thought that I was getting the same result. As soon as I saw this, I hard refreshed and I can see the different results.

Your code snippets really helped me to visualize what is going on behind the scenes, so I can grasp the reduce method easier.

Now I totally understand the difference, as the total was resetting to 0 each iteration in my example.

I seriously can’t thank you enough for this great explanation! Have a great day Kevin :slight_smile:

1 Like