Detailed Explanation of the Array Method Reduce in JavaScript

Detailed Explanation of the Array Method Reduce in JavaScript

Description:
reduce is a higher-order function for JavaScript arrays, used to accumulate array elements into a single value via a callback function. It iterates over the array from left to right, processing each element and maintaining an intermediate result (the accumulator). The core of reduce lies in its "convergence" logic, commonly used for complex operations like summation, flattening, grouping, etc.


1. Basic Syntax of reduce

arr.reduce(callback(accumulator, currentValue, currentIndex, array), initialValue)
  • callback: The function to process each element, containing the following parameters:
    • accumulator: The accumulated value (the return value from the previous callback or the initial value).
    • currentValue: The current array element being processed.
    • currentIndex (optional): The index of the current element.
    • array (optional): The original array.
  • initialValue (optional): The initial value for the accumulator. If omitted, the first element of the array is used as the initial value, and iteration starts from the second element.

2. Detailed Execution Steps

Assuming calling reduce on the array [1, 2, 3, 4]:

Case 1: No Initial Value (initialValue omitted)

const result = [1, 2, 3, 4].reduce((acc, cur) => acc + cur);

Execution Process:

  1. First callback: acc takes the first element 1, cur takes the second element 2, returns 1 + 2 = 3.
  2. Second callback: acc = 3, cur = 3, returns 3 + 3 = 6.
  3. Third callback: acc = 6, cur = 4, returns 6 + 4 = 10.
  4. Final result: 10.

Note: When no initial value is provided, the number of iterations is array length - 1.

Case 2: With Initial Value (initialValue = 10)

const result = [1, 2, 3, 4].reduce((acc, cur) => acc + cur, 10);

Execution Process:

  1. First callback: acc = 10, cur = 1, returns 10 + 1 = 11.
  2. Second callback: acc = 11, cur = 2, returns 11 + 2 = 13.
  3. Third callback: acc = 13, cur = 3, returns 13 + 3 = 16.
  4. Fourth callback: acc = 16, cur = 4, returns 16 + 4 = 20.
  5. Final result: 20.

Key Difference: With an initial value, the number of iterations equals the array length, and the callback starts processing from the first element.


3. Common Use Cases

Case 1: Summation (Basic Usage)

const sum = [1, 2, 3].reduce((acc, cur) => acc + cur, 0); // 6

Case 2: Flattening a 2D Array

const flattened = [[1, 2], [3, 4]].reduce((acc, cur) => acc.concat(cur), []); // [1, 2, 3, 4]

Equivalent to ES2019's Array.prototype.flat().

Case 3: Counting Element Occurrences

const fruits = ['apple', 'banana', 'apple', 'orange'];
const count = fruits.reduce((acc, cur) => {
  acc[cur] = (acc[cur] || 0) + 1;
  return acc;
}, {}); // { apple: 2, banana: 1, orange: 1 }

Case 4: Grouping by Property

const people = [
  { name: 'Alice', age: 21 },
  { name: 'Bob', age: 21 },
  { name: 'Charlie', age: 22 }
];
const grouped = people.reduce((acc, cur) => {
  const key = cur.age;
  if (!acc[key]) acc[key] = [];
  acc[key].push(cur);
  return acc;
}, {});
// Result: { 21: [{...}, {...}], 22: [{...}] }

4. Important Notes

  1. Empty array without initial value throws an error:

    [].reduce((acc, cur) => acc + cur); // TypeError
    

    Always specify an initial value for potentially empty arrays.

  2. Accumulator type is flexible: It can be a number, array, object, etc., depending on the designed callback logic.

  3. Avoid modifying the original array: reduce should be a pure function operation without side effects.


5. Extension: reduceRight

reduceRight has the same logic as reduce, but iterates from right to left:

const result = [1, 2, 3].reduceRight((acc, cur) => acc - cur, 0); // 0 - 3 - 2 - 1 = -6

By mastering reduce, you can replace some loop or recursive logic, making your code more functional and concise.