JavaScript Array reduce() method

In JavaScript, array reduce is a predefined method for lowering an array to a single value by passing a callback function for each array element. It accepts a process run on all the elements of the supplied array in the left-to-right order. The single value returned is saved in the accumulator.

As a result, array reduction JavaScript is a non-mutating technique. Rather than modifying the real value variable, it will store the computed value in the accumulator while leaving the original value variable alone.

The reduce() method calls a user-supplied “reducer” callback function on each array element, sending in the result of the previous element’s calculation. The reducer’s outcome across all array elements is a single value.

“return value of the previous calculation” is not available the first time the callback is executed. In its absence, an initial value may be utilized. On the contrary, the zeroth index array element is used as the starting point, and iteration begins with the following member (index 1 instead of index 0).

The most straightforward use of reduce() is to return the total of all the entries in an array:

<div class="wp-block-codemirror-blocks-code-block code-block">
<pre>const arrayVals = [4, 5, 6, 7];

const initialValue = 0;
const sumWithInitial = arrayVals.reduce(
  (previousValue, currentValue) => previousValue + currentValue,
  initialValue
);

console.log(sumWithInitial);
// expected output: </pre>
</div>

The reducer iteratively travels through the array, adding the value of the current array to the result from the previous step— until there are no more elements to add. Note that the result from the initial step is the running sum of all the previous steps.

The syntax is as follows:

<div class="wp-block-codemirror-blocks-code-block code-block">
<pre>array.reduce(function(total, currentValue, currentIndex, arr), initialValue)</pre>
</div>

Parameters

A “reducer” function is invoked with the following parameters:

previousValue

The outcome of the preceding call to callbackFn. If initialValue is given, the value of array[0] is returned on the first call.

currentValue

The current element’s value. If an initialValue was supplied, the array[0] value is returned on the first call; otherwise, the array[1] is returned.

currentIndex

The array index position of currentValue. If initialValue was given on the first call, 0; else, 1.

arr

It refers to the array that is being traversed.

Total

It is required. The function’s initialValue, or previously returned value – is the accumulated result of the callback function’s last call.

Optional initialValue

A value is initialized when the callback is called for the first time. When initialValue is supplied, currentValue is also set to the first value in the array. If no value is provided for initialValue, previousValue is set to the first in the array, and currentValue is set to the second in the array.

The value returned

The outcome is running the “reducer” callback function through the entire array to completion.

Exceptions: TypeError

There are no elements in the array, and no initialValue is specified.

Description

Reduce() accepts two parameters: a callback function and an optional initial value.

If an initial value is specified, reduce() executes the “reducer” callback function on each array element in the order established. If no initial value is set, reduce() invokes the callback function on each element in the array following the first. reduce() returns the value returned by the callback function on the array’s final iteration.

When to Avoid Using Reduce()

Recursive functions like reduce() can be extremely powerful, but they can also be challenging to grasp, especially for inexperienced JavaScript developers. If other array techniques result in clearer code, developers must consider the readability tradeoff against the other advantages of using reduce().

When reduce() is the best option, documentation and semantic variable name can help to mitigate readability issues.

Cases on the periphery

If the array only has a single element regardless of position and no initialValue is supplied, or if the initialValue is provided, but the array is empty, the solo value is returned without executing callbackFn.

If initialValue is specified and the array is not empty, the reduce method will always call the callback function beginning at index 0. If no initialValue is specified, the reduce method will behave differently for arrays with lengths greater than one, equal to one, and zero, as seen in the following example:

<div class="wp-block-codemirror-blocks-code-block code-block">
<pre>const findMaxValue = (aVal, bVal) => Math.max(aVal, bVal);

// invoking the callback for each element in the provided array starting at index 0
[1, 100].reduce(findMaxValue, 50); // 100
[    50].reduce(findMaxValue, 10); // 50

// callback is invoked once for the element at index 1
[1, 100].reduce(findMaxValue);     // 100

// callback is not invoked
[    50].reduce(findMaxValue);     // 50
[      ].reduce(findMaxValue, 1);  // 1

[      ].reduce(findMaxValue);     // TypeError</pre>
</div>

Observed behavior during array mutations

The reduce() method does not alter the array it is applied to. The array can, however, be changed by code inside the callback function. These are the array of mutation possibilities and how reduce() operates in these scenarios:

If individual items are added to the array after reduce() starts iterating over it, the callback function does not loop through the newly added features.

If existing array members are altered, the values given to the callback function will be the values from the first time reduce() was used on the array. Reduce does not visit array members that are destroyed after the call to reduce() begins and before being iterated over.

How reduce() works in the absence of an initial value

The following code demonstrates what occurs when we execute reduce() with an array when there is no present initial value.

<div class="wp-block-codemirror-blocks-code-block code-block">
<pre>const arrValue = [25, 26, 27, 28, 29];

function reducer(prevValue, currValue, index) {
  const returns = prevValue + currValue;
  console.log(`prevValue: ${prevValue}, currValue: ${currValue}, index: ${index}, returns: ${returns}`);
  return returns;
}

array.reduce(reducer);</pre>
</div>

The callback would be called four times, with the provided parameters and return values in each call.

How reduce() functions with a starting value

Here, we use the same approach to decrease the same array, but with an initialValue of 10 as the second argument to reduce():

<div class="wp-block-codemirror-blocks-code-block code-block">
<pre>[25, 26, 27, 28, 29].reduce((prevValue, currValue) => prevValue + currValue, 10)</pre>
</div>

The total of the values in an object array

To sum the values in an array of objects, you must first provide an initialValue, which ensures that each item travels through your method.

<div class="wp-block-codemirror-blocks-code-block code-block">
<pre>const objValues = [{ x: 1 }, { x: 2 }, { x: 3 }];
const sumValue = objValues.reduce(
  (prevValue, currValue) => prevValue + currValue.x,
  0,
);

console.log(sumValue); </pre>
</div>

Example: Make an array of arrays flat

<div class="wp-block-codemirror-blocks-code-block code-block">
<pre>const flatValue = [[0, 1], [2, 3], [4, 5]].reduce(
  (prevValue, currValue) => prevValue.concat(currValue),
  [],
);
// flatValue is [0, 1, 2, 3, 4, 5]</pre>
</div>

Example: Counting the number of instances of a value in an object

<div class="wp-block-codemirror-blocks-code-block code-block">
<pre>const studentNames = ['Green', 'Angelo', 'Tyson', 'Mike', 'Laird'];

const namesCounted = studentNames.reduce((compNames, val) => {
  compNames [val] ??= 0;
  compNames [val]++;
  // do not forget to return the object, or the subsequent iteration will be undefined
  return compNames;
}, {});
// namesCounted is:</pre>
</div>

Example: Subtracting Numbers in Array

<div class="wp-block-codemirror-blocks-code-block code-block">
<pre>const numbers = [2000, 250, 500, 220, 300];

// subtract all numbers from the first number
// since 1st element is called an accumulator rather than currentValue
// 2000 - 250 - 400 - 220 - 300
let diffVal = numbers.reduce(
  (accumulator, currentValue) => accumulator - currentValue
);
console.log(diffVal); 

const expenses = [2000, 2200, 3200, 5200, 700];
const wages = 15000;

// function that subtracts all array elements from a given number
// 15000 - 2000 - 2200 - 3200 - 5200 - 700
let balValue = expenses.reduce(
  (accumulator, currentValue) => accumulator - currentValue,
  wages
);
console.log(balValue); 
</pre>
</div>

This example demonstrates the distinction between passing an initialValue and not an initialValue.

Example: Organizing items based on a property

<div class="wp-block-codemirror-blocks-code-block code-block">
<pre>const students = [
  { name: 'Green', age: 21 },
  { name: 'Angelo', age: 20 },
  { name: 'Moss', age: 20 },
];

function groupBy(objectArray, property) {
  return objectArray.reduce((acc, obj) => {
    const key = obj[property];
    acc[key] ??= [];
    acc[key].push(obj);
    return acc;
  }, {});
}

const groupedStudents = groupBy(students, 'age')
// groupedStudents is:
// {
//   20: [
//     { name: 'Angelo', age: 20 },
//     { name: 'Moss', age: 20 }
//   ],
//   21: [{ name: 'Green', age: 21 }]
// }</pre>
</div>

Example: Change .filter().map() to.reduce()

Array.filter() and Array.map() traverses the array twice, whereas Array.reduce() achieves the same result while traversing the array just once, making it more efficient. If you prefer for loops, you may use Array.forEach() to filter and map while traversing once.

<div class="wp-block-codemirror-blocks-code-block code-block">
<pre>const numbers = [-5, 6, 2, 0];

const doubledPositiveNumbers = numbers.reduce((previousValue, currentValue) => {
  if (currentValue > 0) {
    const doubled = currentValue * 2;
    previousValue.push(doubled);
  }
  return previousValue;
}, []);

console.log(doubledPositiveNumbers); // [12, 4]</pre>
</div>

Example: Using the spread syntax and initialValue, concatenate arrays in an array of objects.

<div class="wp-block-codemirror-blocks-code-block code-block">
<pre>// programming languages - an array of objects
// where object field "programmingLanguages" is a list of individual favorite programming languages
const programmingLanguages = [
  {
    name: 'Thomas',
    languages: ['Python', 'Django'],
    age: 41,
  },
  {
    name: 'James',
    languages: ['JavaScript', 'AngularJS and React'],
    age: 25,
  },
  {
    name: 'Given,'
    languages: [' Kotlin for Android', 'Java', 'JavaScript'],
    age: 23,
  },
];

// allLanguages - a list that will contain all colleagues'  programming languages
// additional list contained in initialValue
const allLanguages = programmingLanguages.reduce(
  (prevValue, currValue) => [...prevValue, ...currValue.languages],
  ['Alphabet'],
);</pre>
</div>

Conclusion

In JavaScript, the arr.reduce() method reduces an array to a single value by executing a supplied function for each array value from left to right. The function’s return value is saved in an accumulator.

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *