Arrays are powerful.
Unlike other data types — you can store anything in them: Strings, Integers, Booleans, Buffers, and even other Arrays. They can be used as simple data storage, to represent matrixes, and even for complex data structures and algorithms — this flexibility for a wide range of scenarios makes them highly invaluable.
But despite their usefulness, their true potential can only be realized when you know how to use them effectively. Sadly, only a few people do. This is from my recent interactions with others.
Beyond the basic forEach(), map(), and filter() methods, the vast majority of Js developers don't know about other Array methods that can greatly simplify their code, make it more readable, maintainable, and efficient.
This article hopes to change that.
Unlike a textbook, or most youtube videos, I'm not going to throw a thousand and one available array methods in Javascript, Instead, I'm going to walk you through the 4 uncommon but powerful Array methods which I use commonly in my day job as a backend developer.
Without further ado, let's dive in.
1. The Reduce() Array method
This one is quite powerful as it's incredibly useful for performing cumulative calculations or aggregating data. It's recursive, lets you reduce an array into a single value, and it does this by executing the operations embedded in a callback function on each element in the array.
I know that's quite a mouthful, so I will walk you through a clear real-life common example to make it easier to grasp. Don't fret, because once you get it, it unlocks a wide range of opportunities.
Say you have an array of 5 objects, and each object contains a product name, the price, and the quantity a Customer adds to the cart (as shown below)...
const products = [
{ name: 'iPhone 12', quantity: 2, price: 999 },
{ name: 'Samsung Galaxy S21', quantity: 1, price: 799 },
{ name: 'AirPods Pro', quantity: 3, price: 249 },
{ name: 'Nintendo Switch', quantity: 4, price: 299 },
{ name: 'Fitbit Charge 4', quantity: 2, price: 149 }
];
How do you calculate the total price?
These two methods below would work just fine.
// Method 1
let totalPrice = 0;
for (let i = 0; i < products.length; i++) {
totalPrice += products[i].quantity * products[i].price;
}
console.log('Total Price:', totalPrice);
// Method 2
let totalPrice = 0;
products.forEach(product => {
totalPrice += product.quantity * product.price;
});
console.log('Total Price:', totalPrice);
But none of them returns a value, they are just iterators...so you would be playing around with variable names and all that. Verbose code, is less readable, and hard to debug.
On the other hand, you could use the Reduce() and replace the need for clunky For-loops and iterators...
const products = [
{ name: 'iPhone 12', quantity: 2, price: 999 },
{ name: 'Samsung Galaxy S21', quantity: 1, price: 799 },
{ name: 'AirPods Pro', quantity: 3, price: 249 },
{ name: 'Nintendo Switch', quantity: 4, price: 299 },
{ name: 'Fitbit Charge 4', quantity: 2, price: 149 }
];
const totalPrice = products.reduce((accumulator, product) => {
return accumulator + (product.quantity * product.price);
}, 0);
console.log(`Total Price: $${totalPrice}`);
And the best part? It returns a value, so you can plug it directly anywhere you want. For any type of problem, less code is always better.
So let me explain what happened there
The Reduce() method takes in two parameters:
- A callback function, and
- An initial value.
The callback function takes in an accumulator and the current element, then it returns the updated accumulator value based on the operations embedded in it.
While the Initial value(Initial value) is the starting point.
- The reduce() method iterates over each element in the producta array.
- For each iteration, it performs an operation defined by the callback function.
- In each iteration, the callback function multiples the product price and quantity, then adds it to the accumulator.
- The new result is returned and becomes the accumulator value for the next iteration.
- Finally, when the reduce() method finishes iterating over all elements in the products array, the resulting object is assigned to the totalPrice variable.
A big thanks to Web Dev Simplified for introducing me to this method. It's even how I broke down data to be stored in database as Ngrams for a fuzzy search algorithm.
2. The Includes() Array Method
This method checks whether an array includes a specific value. It returns a boolean value (true or false) indicating whether the value is found in the array. It's perfect for simple searches within arrays.
This is why I use it for wading through Mongoose and Express error messages when writing my Error Handlers. What you see below is a Mongoose error after a failed password validation check.
Here's how I fish it out from the heap of error messages so it can be handled properly and appropriately.
//...preceding body of code removed for clarity
if (error.message.includes('Member validation failed')) {
const pinPoint = Object.values(error.errors);
console.log(pinPoint);
pinPoint.forEach(({ properties }) => {
errorObject[properties.path] = properties.message;
})
}
The above code block is part of an Error Handler, it checks if the Error message contains the string "Member validation failed" and evaluates the code in the if statement based on the result.
3. The Some() and Every() Array Method
Both go hand in hand.
The some() method tests whether at least one element in the array passes a given condition specified by a callback function while the Every method checks whether all elements in the array pass the given function.
Both return a boolean value (true or false) indicating whether the condition is met. But the some() method stops iterating through the array as soon as it finds the first element that satisfies the condition.
On the flip side, the Every() method stops iterating through the array as soon as it finds the first element that does not satisfy the condition. Think of the SOME() array method as an OR operator and the EVERY() array method as the AND operator and it will click.
Here's an example for illustration:
const numbers = [1, 2, 3, 4, 5];
const allPositive = numbers.every(number => number > 0);
const isOneElementEven = numbers.some(number => number % 2 == 0);
const areAllElementsEven = numbers.every(number => number % 2 == 0);
console.log(allPositive); // Output: true
console.log(isOneElementEven); //Output: true
console.log(areAllElementsEven); //Output: false
4. The Find() array method
The Find() method works similarly to the Includes() method. But unlike the Includes method which returns a Boolean, the Find() method returns the first element that certifies the search condition and "Undefined" when it finds none.
const fruits = ['apple', 'banana', 'orange'];
const foundFruit = fruits.find(fruit => fruit === 'banana');
const containsFruit = fruits.includes('banana')
console.log(foundFruit); // Output: 'banana'
console.log(containsFruit); // Output: 'true'
Two, Find() takes a callback function while the Include() method takes none. This is why I said the Include() method works well for simple searches but it will fail on complex queries.
const users = [
{ id: 1, name: 'Alice' },
{ id: 2, name: 'Bob' },
{ id: 3, name: 'Charlie' }
];
const foundUser = users.find(user => user.id === 2);
console.log(foundUser);
The includes() method, on the other hand, is not suitable for this task since it performs a simple equality check and does not provide a way to retrieve the matched object. It can only determine whether a specific value exists in an array, but not provide access to the matching element itself.
Therefore, if you need to find and retrieve a specific object from an array based on a condition, the find() method is the appropriate choice over includes().
Few Closing Remarks
1. Most array methods are non-destructive.
This means all the methods highlighted above don't change the underlying Array that you are operating on. In other words, they are non-destructable.
2. Most array methods are quite similar, but they each have distinct purposes.
The forEach Operator and the Map operator are similar. While Map returns a value, forEach doesn't.
3. Most array methods take a callback function.
forEach(), map(), and filter(), all require a callback function to perform their operations. This characteristic makes them known as higher-order array methods.
It was Babatunde Koiki who pointed this out to me.
The callback function passed to these methods allows us to define the specific logic or operation we want to perform on each element of the array.
This article on freecodecamp is a good intro to Higher-order functions.
Javascript has numerous array methods.
We have the shift, unshift, pop, etc but I can't talk about them since I've hardly used them. Instead, I will direct you to someone who has.
Take a read and solve real-life problems using the methods you read about— that's the only way to master them. Here's to more problem-solving with Javascript🥂
Top comments (0)