1. Introduction

The article will deal with this interview question from three aspects: understanding reduce, using reduce and realizing Reduce. Reading this article, you will learn:

1.know`reduce`Functions;2. `reduce`Common usage scenarios of functions;3.0to1To implement a`reduce`Functions;Copy the code

2. Know the reduce

The reduce() method performs a function (ascending) that you provide on each element in the array, summarizing its results into a single return value.

Notice a few keywords: array, per element, function, single return value.

In layman’s terms:

1.Reduce is a method of arrays;2.Each element of the array is processed, and the function being processed is passed as a parameter;3.Reduce returns only one result;Copy the code

Grammar:

arr.reduce(callback(accumulator, currentValue[, index[, array]])[, initialValue])
/ / for
[1.2.3].reduce((acc, cur, index, array) = > (arr + cur), initialValue)
Copy the code

As you can see, reduce takes two arguments: callback function, initialValue initialValue; Where the passed function (callback) that processes each element of the array takes four arguments:

    1. AccumulatorThe cumulative device
    1. Current ValueThe current value
    1. IndexThe current index
    1. arrayThe source array

Each time an element is processed, the callback returns a value that is the accumulator and ultimately a single result.

3. Use the reduce

Common usage scenarios:

3.1 The sum of all values in an array

const arr = [1.2.3.4];
const initVal = 0;
const total = arr.reduce((acc, cur, index, array) = > {
  console.log(acc, cur);
  / / 0 to 1
  / / 1. 2
  / / 3. 3
  4 / / 6
  return acc + cur;
}, initVal);
console.log(total); // Output: 10
Copy the code

As can be seen, in the case that reduce has an initial value, the value of acc of the first iteration accumulator is 0, and the current value is 1. Now remove the initial value:

const arr = [1.2.3.4];
const total = arr.reduce((acc, cur, index, array) = > {
  console.log(acc, cur);
  / / 1. 2
  / / 3. 3
  4 / / 6
  return acc + cur;
});
console.log(total); // Output: 10
Copy the code

It can be seen that the value of acc in the first iteration is 1, and the current value cur is 2, that is to say: in the case of initial value, the accumulator starts to accumulate from the initial value; Without an initial value: The accumulator accumulates from the first element in the array.

3.2 Convert a two-dimensional array to a one-dimensional array

const res = [1[2.3].4].reduce((acc, cur) = > {
  if (typeof cur === "object") {
    acc = acc.concat(cur);
  } else {
    acc.push(cur);
  }
  returnacc; } []);console.log(res);
Copy the code

It is mainly through the concat method of array to accumulate the final one-dimensional array. Of course, converting a two-dimensional array to a one-dimensional array can also be done using the flat method proposed by ECMAScript 2019 (IE is not supported) :

[1[2.3].4].flat(1); // Output: [1, 2, 3, 4]
Copy the code

3.3 Count the number of occurrences of each element in the array

const arr = ['kobe'.'james'.'kobe'.'jim'.'wade'.'wade'.'kobe'];
const res = arr.reduce((acc, cur) = > {
    if(cur in acc) {
        acc[cur]++;
    } else {
        acc[cur] = 1;
    }
    return acc
}, {})
console.log(res) {kobe: 3, James: 1, Jim: 1, wade: 2}
Copy the code

3.4 Classifying Objects by attribute

const players = [
        { name: 'kobe'.number: 24 },
        { name: 'James'.number: 23 },
        { name: 'Jordon'.number: 23 },
        { name: 'George'.number: 24}];const groupe = players.reduce((acc, item) = > {
        if(! (item.numberin acc)) {
            acc[item.number] = [];
        }
        acc[item.number].push(item);
        return acc
}, {})
console.log(groupe)
/ / output
{
    23: [{name: 'James'.number: 23 },
        { name: 'Jordon'.number: 23},].24: [{name: 'kobe'.number: 24 },
        { name: 'George'.number: 24}}]Copy the code

3.5 Calculate the maximum value in an array

const arr = [3.4.9.6.10.2];
const max = arr.reduce((pre, cur) = > Math.max(pre, cur));
console.log(max) // Output: 10

// You can also use 'math.max' in conjunction with the extension operator to find the maximum value
Math.max(... arr)// Output: 10
Copy the code

3.6 Array deduplication

const arr = [3.4.3.6.10.4.5];
const newArr = arr.reduce((retArr, cur) = > {
    if(retArr.indexOf(cur) === -1) {
        retArr.push(cur);
    }
    return retArr
}, [])
console.log(newArr) // Output: [3, 4, 6, 10, 5]

// This can also be implemented using the Set data structure
[...new Set(arr)]; // Output: [3, 4, 6, 10, 5]
Copy the code

4. Handwriting implementation

Through the above usage scenarios, we have some understanding of reduce function. First, we will analyze the implementation steps:

    1. Reduce is a function and has a return value;
    1. Reduce takes two arguments, the first a callback function and the second an initial value (optional).
    1. The callback function takes four arguments: the accumulator, the current value, the current index, and the original array.
    1. The callback function returns a value that is assigned to the first argument;

Do it:

Array.prototype.selfReduce = function (callback, initValue) {
        // Get the source array
        const originArray = this;

        // Determine if the source array is empty and throw an exception if it is
        if(! originArray.length) {throw new Error('selfReduce of empty array with no initial value');
        }

        // Declare the accumulator
        let accumulator

        // Whether there is an initial value case
        // Set the initial value of the accumulator (if there is an initial value, the first parameter of 'callback' when first called is the initial value, otherwise it is the first item of the source array)
        if (initValue === undefined) {
            accumulator = originArray[0];
        } else {
            accumulator = initValue;
        }

        // Iterate over the number group and execute 'callback'
        for (let i = 0; i < originArray.length; i++) {
            // If this is the last loop, no callback is executed
            if((i + 1) === originArray.length) break;

            // Loop through 'callback'
            // check 'currentValue' here
            // Because 'currentValue' is' originArray[I] 'when there is an initial value
            // With no initial value, 'currentValue' is' originArray[I + 1] '
            accumulator = callback(accumulator, initValue === undefined ? originArray[i + 1] : originArray[i], i, originArray);
        }

        // Return the accumulator
        return accumulator
}
Copy the code

Verify:

// Find the maximum value
const r = [2.4.8.1].selfReduce((a, b) = > Math.max(a, b))
console.log(r) // Output: 8

// Array element summation
const arr = [1.2.3.4];
const initVal = 0;
const total = arr.reduce((acc, cur, index, array) = > {
        console.log(acc, cur);
        / / 0 to 1
        / / 1. 2
        / / 3. 3
        4 / / 6
        return acc + cur;
}, initVal);
console.log(total); // Output: 10
Copy the code

At this point, the reduce function is basically realized.

5. To summarize

During the interview process, you will often be asked questions about implementing native apis by hand; If you really asked, don’t be particularly nervous, in fact, as long as you comb your thoughts, it is not so difficult; If it is a function, it is necessary to start from the parameters of the function, return value analysis, step by step to achieve, basically there is no problem.