This is the sixth day of my participation in the First Challenge 2022

In business development, we often deal with arrays, converting them into the data we need. Therefore, we often use array instance methods, such as forEach, Map, filter, etc., which conform to the single responsibility principle, simple and easy to understand, suitable for beginners.

The Reduce method, on the other hand, is less well understood, but it is more flexible and suitable for older people to write fancy code.

Today, WATERMELON, I’m going to talk about Reduce.

What is array.prototype. reduce?

Array.prototype.reduce is used in an iteration to execute the callback function and pass the value returned by the callback function to the next iteration. Take the value returned by the last iteration as the return value of reduce.

What about the word reduce? The most common meaning of reduce is “reduce”. Depending on usage, it may be better translated as “fold”. The reduce method carries the results of each iteration to the next iteration, and finally folds the two-dimensional lines (arrays) into one-dimensional points. Although the return value may also be an array, it still counts as a point from the dimension of the return value.

Continue to explain the use of reduce in more detail.

Reduce receives two parameters.

The first parameter is the callback function reducer.

The Reducer callback accepts four parameters provided by Reduce:

  1. Accumulator: Is the return value of the callback function executed in the previous iteration
  2. CurrentValue: The value of the array element for the current iteration
  3. Index: Index of the array element for the current iteration
  4. Array: indicates the source array

The value returned by the current Reducer will be passed into the callback function in the next iteration.

The second argument is the initial value and is optional.

If no initial value is provided, Reduce takes the first element as the initial value of the accumulator and iterates from the second array element.

If an initial value is provided, Reduce takes it as the accumulator’s initial value and iterates from the first array element.

Note that an empty array does not provide an initial value, resulting in a type error. It is recommended to provide an initial value as much as possible to accommodate the special case of an empty array.

Uncaught TypeError: Reduce of empty array with no initial value
Copy the code

A simple implementation of Reduce

To really understand how this amazing Reduce works, you have to implement it yourself. Here I implement a simple reduce method:

Array.prototype.myReduce = function(callbackFn, initVal) {
  const arr = this;
  if (typeofcallbackFn ! = ='function') {
    throw new TypeError(callbackFn + ' is not a function');
  }
  let i = 0;
  let acc = initVal;
  if (arguments.length < 2) { // No initial value is provided
    if (arr.length === 0) {
      throw new TypeError('Reduce of empty array with no initial value');
    }
    acc = arr[0];
    i = 1;
  }

  for (; i < arr.length; i++) {
    acc = callbackFn(acc, arr[i], i, arr);
  }
  return acc;
}
Copy the code

The core code is to check whether a second argument (the default argument) is provided by arguments.length.

If provided, the accumulator variable is set to the default value passed in, and the iteration starts at index 0 (I = 0); If not provided, the accumulator variable sets the first array element and the iteration starts at 1.

Do not rely on whether the second argument is undefind, because undefind can also be passed in as the default.

Some uses of reduce

The most common use of reduce is to sum an array as follows:

const arr = [1.2.3];
const sum = arr.reduce((sum, cur) = > sum + cur, 0); / / 6
Copy the code

To accommodate empty arrays, it is recommended to add an initial value of 0.

In the ES5 era, Reduce can also do the following:

  1. Flatten a two-dimensional array, now useArray.prototype.flat;
  2. Array deduplicate, now useArray.from(new Set(arr));
  3. .

In fact, forEach can implement these as well. Like summation.

const arr = [1.2.3];
let sum = 0;
arr.forEach(val= > { sum += cur }); 
Copy the code

But reduce has the advantage of not having to declare a variable outside the method, which is more elegant.

And if the sum variable name changes, the reduce function does not need to change it.

Why is Reduce flexible?

Reduce is flexible because it can return values of any type other than an array. For example, if you want to convert an array to an object using a specific rule, reduce is a good fit.

This means that Reduce is an iterator with the flexibility to return any type of value.

It can implement single-purpose methods like forEach, Map, filter, and find. It doesn’t have to, but it does.