DEV Community

Samuel Tope
Samuel Tope

Posted on • Originally published at Medium on

Reducing Your Array The Right Way

Reducing Your Array The Right Way

Image credits: Pixabay

One of the benefits of Javascript as a language is that it allows us to write functional style of programming, that is, we write programs by composing functions which describe actions (what should happen) and abstracts the processes (how it should happen). This style of programming is possible in javascript because functions are first-class citizens, they are data and can be passed around in your application like variables.

Pure Functions

One of the core tenet of functional programming is writing pure functions. Pure functions are functions that have no free variables, i.e all its variables comes from its arguments, thereby making it return the same value for the same arguments, It has no side-effects on the program because it does not change the program state.

If a pure function needs to mutate or modify any variable(arguments) passed to it, it will create a copy, modify and return the copy, leaving the original variable untouched. This is called immutability. The essence of functional programming is using functions to transform data from one form to another, like i mentioned earlier, these data are copied before being transformed thereby leaving the original data intact. This improves readability, testability and correctness of our program.

Array.prototype.reduce And Array.prototype.reduceRight

Array is a basic data structure in javascript there are several operations we can perform on an array by applying functions to it. We will be taking a look at two of these functions in this article. They are called reduce (Array.prototype.reduce) and reduceRight (Array.prototype.reduceRight). What these functions does is to process an array by iterating over its elements and building up a single value that is returned based on a specified criteria.

reduce() and reduceRight() works in the same way except that reduce() starts from the first item in the array to the last while reduceRight() starts from the last item to the first.

Both reduce() and reduceRight() accept two arguments, a function that performs the reduction operation (a reducer) and an optional initial value with which the reducer starts its operation. The reducer accepts four arguments: the previous item (also called the accumulated value), the current item, the current item’s index and the array itself. The first two arguments of the reducer is commonly used. The value returned from each iteration (the accumulated value) is passed to the next iteration as the first argument.

The reduce() and reduceRight() uses a reducer, the reducer is the function that does the actual calculation on each iteration.

Examples

Lets use a basic example to illustrate how reduce works, we are going to sum up the elements of an array using the reduce function.

let numbers = [2,4,6,7,8];
let sum = numbers.reduce((acc, cur) => {
 return acc + cur;
});
console.log(sum); // 27

There are five elements in the numbers array, the reducer will iterate through the elements using the first value (2) as the intial accumulator (acc). Lets see what each value looks like for each iteration.

First iteration => acc = 2, cur = 4, acc + cur = 6
Second iteration => acc = 6, cur = 6, acc + cur = 12
Third iteration => acc = 12, cur = 7, acc + cur = 19
Fourth iteration => acc = 19, cur = 8, acc + cur = 27

if a second argument is passed to the reduce function like this

let numbers = [2,4,6,7,8];
let sum = numbers.reduce((acc, cur) => {
 return acc + cur;
}, **20** );

console.log(sum); // 47

It will be the first argument to the reducer and the iteration will occur five times instead of four like this:

First iteration => acc = 20, cur = 2, acc + cur = 22
Second iteration => acc = 22, cur = 4, acc + cur = 26
Third iteration => acc = 26, cur = 6, acc + cur = 32
Fourth iteration => acc = 32, cur = 7, acc + cur = 39
Fifth iteration => acc = 39, cur = 8, acc + cur = 47

The best practice is to initialize the reduce function to a reasonable default by providing a value as the second argument of the reduce function.

To find the largest number in an array using the reduce function:

const numbers = [20,22,50,60,12];
const largestNumber = numbers.reduce((max, num) => {
 console.log(`${num} > ${max} is ${num > max}`); 
 return (num > max) ? num : max
}, 0);

console.log(largestNumber); // 60

In the above example, the max variable was initialized to 0, on each iteration, the reducer compares the current max value with the current element (num) and returns the greater of the two values, the returned value is assigned to the max variable and its used for the next iteration.

To remove duplicate elements in array using the reduce function:

let numbers = [1, 2, 1, 2, 3, 5, 4, 5, 3, 4, 4, 4, 4];

let distinctNumbers = numbers.reduce((distinct, num) => {
 return (distinct.indexOf(num)) !== -1 ? distinct : [...distinct, num];
}, []);

console.log(distinctNumbers); // [1,2,3,5,4]

Note that the reduce function was initialized to an empty array because we are expecting an array as our result, this is the reasonable default. What the reducer is doing in this example is to check if a number already exists in the initialized array, add it if it doesn’t exist, and return the array. The spread operator is used here.

Lets have one more example to illustrate reduceRight(). Assuming we need to perform an operation that has a right to left precedence, like an arithmetic operation. Lets see an example below:

Compute 3^(3^2)
// We calculate (3 ^ 5) first, assuming the result is n, we then calculate (2 ^ n) to get the final answer.

let numbers = [3,3,2];
let answer = numbers.reduceRight((ans, num) => {
 return Math.pow(num, ans);
});

console.log(answer); // 19683

In the example below, the reducer starts from the right (2), In the first iteration, the calculation will be (3²) which is 9, the second iteration will be (3⁹) which is 19683.

Conclusion

I have just shown you a little of the capabilities of reduce() and reduceRight(), They have more use-cases than what we have treated here. To learn more, check out the MDN docs. Sarah drasner also wrote an article on css-tricks.

Thanks for Reading

Top comments (2)

Collapse
 
enriquemorenotent profile image
Enrique Moreno Tent

I think you tried to do mark up in your code, to make it bold:

}, **20** );

but it didn't work

Collapse
 
conaxliu profile image
ConaxLiu • Edited

Is the comment on the second line in the reduceRight example correct?