FAQ: Iterators - The .reduce() Method

This community-built FAQ covers the “The .reduce() Method” exercise from the lesson “Iterators”.

Paths and Courses
This exercise can be found in the following Codecademy content:

Web Development

Introduction To JavaScript

FAQs on the exercise The .reduce() Method

Join the Discussion. Help a fellow learner on their journey.

Ask or answer a question about this exercise by clicking reply (reply) below!

Agree with a comment or answer? Like (like) to up-vote the contribution!

Need broader help or resources? Head here.

Looking for motivation to keep learning? Join our wider discussions.

Learn more about how to use this guide.

Found a bug? Report it!

Have a question about your account or billing? Reach out to our customer support team!

None of the above? Find out where to ask other questions here!

Not unless we consider the dictionary meaning of the words, and no they are not built into JavaScript.

Parameters are locally defined variables (in function scope). We declare them arbitrarily, but in keeping with common sense use terms that describe what the variable references, or its purpose.

(accumulator, currentValue) => accumulator + currentValue

The above callback is kept going until the object array is reduced to a single value. The array itself is unchanged. Put in simple terms,

Array.reduce((a, b) => a + b))

In a sense we can think of a as being the first term in the array, and b as the last. The last term is popped off the array and added to the first term, and the new value replaces the first term. This process is repeated until there is only one term, which is the resulting value of the method.

The heavy lifting is done by the reduce method, which has a built-in iterator for stepping through the array object.

Consider this mockup of the possible code behind the method…

function reduce(array) {
  var clone = array.slice();  // a copy so the original is untouched
  while (clone.length > 1) {
    clone[0] += clone.pop();
  }
  return clone[0]
}
array = [1,1,2,3,5,8,13,21,34,55]
console.log(reduce(array))    // 143
5 Likes

Does the first chart of results miss the first iteration? Shouldn’t row 1 be:
Iteration accumulator current val return val
first 1 1

Study the array, then fill in the blanks in the table. Compute the sum and store in column 4.

[1, 2, 4, 10]

We first load the accumulator with the leftmost element of the array (index 0).

First    1

The currentValue is the next element in the array (index 1) which gives,

First    1    2

Now we compute the sum and return it. This becomes the accumulator in the second iteration. The index pointer is incremented and the process repeated.

First    1    2    3

If we were to use the algo posted earlier, the table would look like,

First      1    10    11
second    11     4    15
Third     15     2    17

since we load the currentValue with the rightmost element in the array.

2 Likes

2 posts were split to a new topic: What is a real world application of .reduce()?

13 posts were split to a new topic: How does .reduce() actually work?

For step one (and only step one, not moving on) I write:

const newSum = newNumbers.reduce( => {
  
});

But this is incorrect. What please is correct line of code for step one?

The function lacks the required two formal parameters:

(a, b) => {
    return a + b;
}

Thank you! That was a great explanation and now I feel like I actually understand what’s going on in the example they used for teaching the reduce() method.

1 Like

can someone puhleaze!!! edit the exercises and make it more understandable?

6 Likes

I’m confused about the ‘second argument’ idea. How does this work???

const numbers = [1, 2, 4, 10];

const summedNums = numbers.reduce((accumulator, currentValue) => {
return accumulator + currentValue
}, 100) // <- Second argument for .reduce()

console.log(summedNums); // Output: 117

Sorry to pop by again, but I just don’t get it…

THIS …

const newNumbers = [1, 3, 5, 7];

const newSum = newNumbers.reduce((accumulator, currentValue) => {
console.log('The value of accumulator: ', accumulator);
console.log('The value of currentValue: ', currentValue);
return accumulator + currentValue;
}, 10);

console.log(newSum);

RETURNS THIS…

The value of accumulator: 10
The value of currentValue: 1
The value of accumulator: 11
The value of currentValue: 3
The value of accumulator: 14
The value of currentValue: 5
The value of accumulator: 19
The value of currentValue: 7
26

BUT THE ACCUMULATOR WAS ONLY DECLARED WITHIN THE CALLBACK FUNCTION, so how can it be that 10, which was only used as an argument outside of the callback function, can somehow equate to the accumulator???

The reduce method permits us to specify an initial value to accumulate from. That is the second argument. If omitted, the value is defined by the type of data in the array. It could be an empty string or zero (for addition) or one (for multiplication), depending whether working with character data or numbers. The initial value is loaded into the accumulator and the process of winding down the array begins, one value at a time computed with the accumulator value.

join() is a form of reducing an array to form a string.

a = 'abcdefghijklmnopqrstuvwxyz'
"abcdefghijklmnopqrstuvwxyz"
a.length
26
b = a.split('')
(26) ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z"]
c = b.reduce((u,v) => u + v, "$ ")
"$ abcdefghijklmnopqrstuvwxyz"
c = b.reduce((u,v) => u + v)
"abcdefghijklmnopqrstuvwxyz"
a = '1234567'
b = a.split('').reduce((u, v) => +u + +v)
28
c = a.split('').reduce((u, v) => +u * +v)
5040

What happens if I try to pass only one argument into .reduce method?

const numbers = [1, 2, 4, 10];
const summedNums = numbers.reduce((accumulator) => {
  return accumulator + accumulator
})
console.log(summedNums) // Output: 8

Why is the output 8?

As near as I can tell that outcome is,

2 ** (numbers.length -1)

As the array size is increased the outcome goes up in powers of two.

At any length, the reduce method functions correctly when we give the callback two parameters.

summedNumbers = numbers.reduce((a, b) => a + b)
1 Like

Here’s why the output is 8.

Since you do not provide an initial value (second argument) in your call to reduce, the first element (index 0) in the array is passed as the initial value of accumulator the first time reduce calls your callback. In addition, the second element (index 1) of the array is passed as the second argument to the callback the first time the callback is called.

After the first call to the callback, each subsequent call receives the value returned from the previous call as the first argument, and the next element in the array (continuing with the element at index 2) as the second argument.

So here are the calls that reduce performs on your callback, where I’ve given your callback the name callback as the name that the reduce method might use for it internally:

callback(1, 2) // returns 2 (1 + 1)
callback(2, 4) // returns 4 (2 + 2)
callback(4, 10) // returns 8 (4 + 4)

Because your callback ignores the second argument, there are only 2 things that affect the result: (1) the first element in the array, and (2) the length of the array.

If the array is empty, you’ll get an exception because you don’t supply a second argument to reduce. Otherwise, the result is numbers[0] * 2 ** (numbers.length - 1)

3 Likes

Okay, a question for how this function works…

const newNumbers = [1, 3, 5, 7];

const newSum = newNumbers.reduce((accumulator, currentValue)=> {
  
  console.log('The value of accumulator: ', accumulator);
  console.log('The value of currentValue: ', currentValue);
  console.log(accumulator);
  return accumulator + currentValue;
  console.log(accumulator);
  
});

console.log(newSum, 'Outside function');
  1. Inside the function newSum, nothing will log to console if the return is set first. Why is that? Shouldn’t it just not display the first couple of numbers? Why does it totally disrupt it? To see an example, the console.log(accumulator) will show what the accumulator is up until the last one. Why won’t it display like this?

NEVERMIND lol:

The return statement ends function execution and specifies a value to be returned to the function caller.

const newNumbers = [1, 3, 5, 7];

const newSum = newNumbers.reduce((accumulator, currentValue) => {
console.log('The value of accumulator: ', accumulator);
console.log('The value of currentValue: ', currentValue);
return accumulator + currentValue;
});

// BEFORE THE CONSOLE.LOG()
//The value of accumulator:  1
//The value of currentValue:  3
//The value of accumulator:  4
//The value of currentValue:  5
//The value of accumulator:  9
//The value of currentValue:  7

//AFTER THE CONSOLE.LOG()

//The value of accumulator:  1
//The value of currentValue:  3
//The value of accumulator:  4
//The value of currentValue:  5
//The value of accumulator:  9
//The value of currentValue:  7
//16

console.log(newSum);

Before the console.log, why does all of that “value of” appear? I thought you had to actually call the function to make the stuff appear??? If that is true, then the 16 should appear before the console.log, and when you log it, it should appear again… I am confused…

EDIT: Also, when I called the function newSum(), an error appeared.

The last values don’t get logged because the iterator is finished.

newSum is not a function. It is a number, the result of the reduce process.

All right, the .reduce method cannot be used with a function expression.

Why? Because it requires more than one parameter for the call, and we all know you don’t pass parameters to a callback function, just the name of it. If the reduce now requires TWO parameters, where does the callback reference go?

I’m not comfortable using the fat arrow approach to define a callback function. It’s messy and does not clearly show the logic.

Update: Okay, I ignored the warning message and got it to work, according to the console.log() output, but really, it should still allow this. Function expressions have not been depreciated yet so this code is right.