简体   繁体   中英

how does initialValue work in javascript reduce function?

I'm sure I'm reading this wrong but MDN says this...

initialValue
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.

then says this ...Aren't these saying different things? Thanks!

If initialValue isn't provided, reduce() will execute the callback function starting at index 1, skipping the first index. If initialValue is provided, it will start at index 0.

The wording is a bit confusing, I agree.

Putting the two statements together:

If no initial value is supplied, the first element in the array will be used

If initialValue isn't provided, reduce() will execute the callback function starting at index 1, skipping the first index

These two statements are actually describing two different characteristics of the reduce operation when no initial value is provided:

  1. The default value used as the initial value
  2. The starting array index that the operation will use

Does this wording make more sense?:

If no initial value is provided, the first element will be used as the initial value. In this case, the callback function will start at index 1, since index 0 has already been accounted for by using it's value as the default starting value.

Unfortunately, I can't just add a comment. Try this , please. This is another explanation of .reduce() function with an example how it works on http://javascript.info . Probably, it will help you to understand this better.

Also, here is the answer to your question about an exception on an empty array without the initial value in another StackOverflow's discussion.

If no initialValue was provided, then previousValue will be equal to the first value in the array and currentValue will be equal to the second. It is a TypeError if the array contains no elements and initialValue is not provided.

Update: probably, this article How JavaScript's Reduce method works, when to use it, and some of the cool things it can do on freeCodeCamp will be useful.

In short: [a,b,c].reduce(...) and [b,c].reduce(..., a) are sometimes the same thing. A better way to think about it, is that the initialValue is actually the first intermediate result of your calculation.

Basic working of reduce

To get a better understanding of how reduce works, use the following sum(a,b) function which logs a text like a+b=c for each operation it performs.

 function sum(a,b) { const c = a + b; console.log(`${a} + ${b} => ${c}`) return c; } const arr = [1,2,4,8]; const result = arr.reduce(sum); console.log(`result=${result}`)

This prints 1+2=3 , 3+4=7 , 7+8=15 and finally result=15 .

Corner case: 1 element

const arr = [1];
const result= arr.reduce(sum);
console.log(`result=${result}`)

If there's just one element in the array. Then it won't even call the supplied function at all. It will just return the single element . So in this case it will just print result=1 .

Corner case: 0 elements

const arr = [];
const result = arr.reduce(sum);
console.log(`result=${result}`)

If there are no elements and no initial value, then it just throws an error: Uncaught TypeError: Reduce of empty array with no initial value

How to prepare for empty arrays:

Of course you could just add a check in your code to check the length of your array.

A pretty solid workaround would be to add an initial value in front of your array.

const arr = [];
const arr2 = [0, ...arr];
const result = arr2.reduce(sum)

The initialValue parameter offers a better solution. It's tempting to say that initialValue actually does the same thing. That would be incorrect.

const result = arr.reduce(sum, 0);

In the context of this example however, both lead to the same result. However, actually the initialValue is not an input value, but it is more like the initial sum.

Working with objects:

There is a small difference, which only becomes obvious if you start using reduce for more complicated transformations.

const inputs = [{value: 1}, {value: 2}, {value:3}];
const total = inputs.reduce((sum, input) => sum + input.value, 0);

The example above again creates a total, but this time it extracts the input from a property value . We have an input of objects, and a numeric result. In this kind of example an initialValue is not optional at all. It's mandatory.

Think about what would happen if you didn't have an initialValue in this example. What would be the value of sum in the first iteration ? sum would actually be {value: 1} which wouldn't even be a number.

So, in this example it's pretty clear that the initialValue is actually the first intermediate result of your calculation.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM