Returning Arrays and Objects from the reduce() Method

Tricks you probably didn’t know about the reduce() method

Femi Majek
Stackademic

--

Photo by Christopher Gower on Unsplash

Introduction

At this point, you’re likely already familiar with most array methods, most especially the map(), filter(), and reduce() methods. However, what you probably didn’t know is that some of the things you’d originally do with the map() and filter() methods can also be done using the reduce() method. We can return arrays and even objects from the reduce() method, as well as use it as a counter depending on the task it’s needed for. Without wasting much time, let’s look at some of these scenarios where the reduce() method could come in handy.

Using reduce() instead of filter()

Suppose we’re giving an array ages that contains ages of different people and we’re asked to make an array of the ages that fall within the age required to obtain a driver’s license(i.e. ages >= 18). Ordinarily, we’d do this using the filter() method like this;

const ages = [14, 19, 16, 23, 12, 38, 20, 17, 10, 18];

const legalAge = ages.filter((el) => el >= 18);

console.log(legalAge); // the result returns [19, 23, 38, 20, 18]

The result of legalAge returns the array of ages that meet the age requirement needed to obtain a driver's license(which are ages greater than or equal to 18). We can however do the same thing above using the reduce() method and still get the same result.

const ages = [14, 19, 16, 23, 12, 38, 20, 17, 10, 18];

const ageLegal = ages.reduce((acc, el) => {
if (el >= 18) acc.push(el);
return acc;
}, []);

console.log(ageLegal); // result returns [19, 23, 38, 20, 18]

To achieve this, we’ll need a function body and also need to initialize our accumulator(acc) as an array. In our reduce() method we then set a condition that pushes the current element in the iteration into our accumulator array(acc) only if it’s greater or equal to “18” and also explicitly return our accumulator(because in a function body, the accumulator doesn’t get returned automatically).

Using reduce() instead of map()

Supposing we’re given an array of values then asked to divide the values of this array by two and store the result in a new array, we could do this with the map() method like this;

const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9];

const arrHalf = arr.map((el) => el / 2);

console.log(arrHalf);
// result returns [0.5, 1, 1.5, 2, 2.5, 3, 3.5, 4, 4.5]

Alternatively, we could also use the reduce() method for the task like this;

const halfRed = arr.reduce((acc, el) => {
acc.push(el / 2);
return acc;
}, []);

console.log(halfRed);
// result returns [0.5, 1, 1.5, 2, 2.5, 3, 3.5, 4, 4.5]

We initialize our accumulator as an empty array and then push the current element divided by two into the array in each iteration, the accumulator is also explicitly returned.

Returning an object from the reduce() method

Supposing we’re given an array containing a set of transactions (withdrawals and deposits), and we’re told to make an object that contains the properties deposits and withdrawals based on the given array. Here’s how we’d go about it using the reduce() method;

const transactions = [-100, 200, 350, -400, -10, 30, -8, 120, 20];

const transactionObj = transactions.reduce(
(acc, el) => {
el < 0 ? (acc.withdrawals += el) : (acc.deposits += el);
return acc;
},
{ deposits: 0, withdrawals: 0 }
);

console.log(transactionObj);
// result returns {deposits: 720, withdrawals: -518}

Our accumulator is initialized as an object containing the properties deposits and withdrawals with both having initial values of zero. Then in each iteration, using the ternary operator we add the current array value to the deposits or withdrawals properties depending on whether it’s (i.e. the current value) greater than zero or not. Finally, we also explicitly return our accumulator object.

Counting with the reduce() method

Assuming we’re told to count the number of deposits in the transactions array from above(i.e. Transactions greater than zero), without much thought we could use the filter() method to filter for the values greater than zero and simply take the length of the returned array as we have below;

const transactions = [-100, 200, 350, -400, -10, 30, -8, 120, 20];

const numDeposits = transactions.filter((el) => el > 0).length;

console.log(numDeposits); // result returns 5

As seen above the numDeposits returns the value 5 which is the result of the number of deposits in the transactions array. Alternatively, we could also do it with the reduce() method like this;

const transactions = [-100, 200, 350, -400, -10, 30, -8, 120, 20];

const depositsNum = transactions.reduce((acc, el) => (el > 0 ? ++acc : acc)
, 0);
console.log(depositsNum); // result returns 5

In the above method, our accumulator is initialized as zero, and then in each iteration using a ternary operator we add one to the accumulator if the current element is greater than zero and return the accumulator from the previous iteration if the current element is less than zero. Note that we used ++acc instead of acc++, this is because directly returning acc++ doesn’t give the desired result as zero is returned in each iteration.

Conclusion

This article is in no way aimed at convincing readers to abandon the traditional methods they use in carrying out operations on arrays that they’re already used to. Instead, it’s just to show readers some other nice ways of carrying out array operations in JavaScript using the reduce() method and also show a few enhanced(unconventional) functionalities that can be implemented with the reduce() method. Thank you for reading and happy coding.

Stackademic

Thank you for reading until the end. Before you go:

  • Please consider clapping and following the writer! 👏
  • Follow us on Twitter(X), LinkedIn, and YouTube.
  • Visit Stackademic.com to find out more about how we are democratizing free programming education around the world.

--

--

Chemistry graduate now exploring the beautiful world of tech as a self-taught Frontend Web Developer. Twitter:@olaoluphemy