11 Lesser-Known JavaScript Array Methods

11 Lesser-Known JavaScript Array Methods

These methods will make working with Arrays possible in ways you would not have thought!

ยท

11 min read

In JavaScript, Arrays are sequential datatype that allows you to store any form of elements or objects in a list and access it later using indexing. One of the core skills of being a software developer is to work with any type of data in your JavaScript files. We may have to manipulate, delete or create any sequential data and doing so is not that easy. Thankfully JavaScript provides us with Array and a plethora of Array methods to work with so that we can work on any type of sequential data easily and effectively.

You may already have heard about some must-know methods for Arrays such as indexOf(), map() and reduce() However, there are a lot more Array methods to explore and today we will be looking at 11 such methods that are in-built into JavaScript Arrays and allows us to do a lot more with Arrays! After reading this article you will have a solid understanding of how many more ways you can manipulate Arrays!

Before we begin

We need to know and understand what some of these Array methods return to us.

Some of these Array methods will return a new Array. Some will return nothing (or undefined) and some will return us a Shallow copy of the Array

What is a Shallow copy?

A Shallow copy of an Array is a copy whose elements will share the same reference with the original Array from which the Shallow copy was created. What this means that is when you make a Shallow copy of an Array, it returns a new Array, completely different from the original Array, as they both have different references. But the elements within those Arrays, are still the same element, they are pointing toward the same memory location. So if you make any change to these elements, whether from a new Array or original Array, the value will change in both locations. But, if you completely replace the element with something new (Remember that here we are changing the Array and not the element itself), the element will remain the same at the other location and won't be replaced. We destroyed the reference to the source element and assigned a new value on the spot.

This is an important detail you need to know when working with JavaScript Arrays as some of the prototype methods do return a Shallow copy of itself and not a deep copy.

Array.concat()

This method concatenates (or merges) two or more Arrays into one.

const furniture = ["Fan", "Table", "Desk"]
const newFurniture = ["Sofa", "Bed"]

console.log(furniture.concat(newFurniture));
// Output: [ 'Fan', 'Table', 'Desk', 'Sofa', 'Bed' ]

console.log(furniture.concat(newFurniture, ["Chair", "Teapoy"]));
// Output: [ 'Fan', 'Table', 'Desk', 'Sofa', 'Bed', 'Chair', 'Teapoy' ]

Array.every()

This method takes a predicate function as its argument and tells whether all the elements present within the Array meet the predicate's condition or not. If any of the elements don't meet the condition, it will return false. If all the elements meet the condition, the method will return true.


const numbers = [43,67,49,23,32]
console.log(numbers.every(x => x < 50)); // false
console.log(numbers.every(x => x < 100)); // true

Array.fill()

This method will fill the Array with a value. If there are 10 elements in the Array, it will change all the elements with that value which we pass as an argument.

This method could be useful to initialize Arrays of big length and put some placeholder values in place of them, but you don't want to use for loop to do it.

console.log([1,2,3,4,5].fill("Samir"))
// Output: [ 'Samir', 'Samir', 'Samir', 'Samir', 'Samir' ]

console.log([1,2,3,4,5].fill("Samir", 2, 4))
// Output: [ 1, 2, 'Samir', 'Samir', 5 ]

console.log(Array(10).fill(""));
// Output: [
//   '', '', '', '', '',
//   '', '', '', '', ''
// ]

Array.filter()

This method will return an Array of filtered elements that meet the predicate passed as an argument. It only takes one argument i.e. the predicate function and returns a Shallow Copy of the elements.

One of the useful higher-order functions you shall know and will be working with frequently.


const players = [
    {name: "A", isOut: true}, {name: "B", isOut: false},
    {name: "C", isOut: true}, {name: "D", isOut: false}
]
console.log(players.filter(player => player.isOut === true));
// Output: [ { name: 'A', isOut: true }, { name: 'C', isOut: true } ]

Array.find()

This method takes a predicate function as an argument and runs it on every element of the Array. The first element which meets the conditions of the function will be returned.

This method is similar to filter() except it will return the first element in the Array only which meets the criteria specified in the predicate.

const something = [1, "two", 3, "four", 5, 6]
console.log(something.find(elem => typeof elem === 'string'));
// Output: 'two'

Array.forEach()

If you want to perform an operation on each element of an Array, then you don't have to use for ... of the loop to achieve this. Arrays have an in-built method to do this!

This method will take a function as an argument and execute it on each element of the Array. This method returns undefined meaning it returns nothing.

const fruits = [
    {name: "Mango", rotten: false }, {name: "Apple", rotten: true },
    {name: "Oranges", rotten: false }, {name: "Banana", rotten: true }
]

let rottenFruits = []
let goodFruits = []

fruits.forEach(fruit => {
    if (fruit.rotten)
        rottenFruits.push(fruit)

    else if (!fruit.rotten)
        goodFruits.push(fruit)
})
console.log("Rotten fruits: ", rottenFruits, "\nGood fruits: ", goodFruits);
// Output:
// Rotten fruits: [ { name: 'Apple', rotten: true }, { name: 'Banana', rotten: true } ]
// Good fruits: [ { name: 'Mango', rotten: false }, { name: 'Oranges', rotten: false } ]

This method can be useful when you want to evaluate all the elements of an Array and based on that do something on other objects or Arrays to reflect the changes.

There are many more use cases for it, find them out!

Array.isArray()

To check whether an object or a value is in the form of an Array, use this method!

Remember that if you do typeof [] it will return an 'object' so it's not a reliable way to determine if it is an Array or not.

[ [], Array(1), {}, [22], [[]], "" ].forEach(elem => console.log(Array.isArray(elem)));
// Output:
// true
// true
// false
// true
// true
// false

Array.some()

Like Array.every(), this method will check if at least one element in the Array meets the predicate function!

This method takes a predicate function as its argument and tells whether at least one of the elements present within the Array meets the predicate's condition or not. If none of the elements meets the condition, it will return false. If one of the elements meets the condition, the method will return true.

const group = [435, 1234, 562, 123]
console.log(group.some(elem => elem > 1000));
// Output: true

Array.shift()

This method pops an element from the Left side.

Unlike pop() which will pop and returns the last element of the Array, this one pops and returns the first element of the Array

const cricketers = ["Dhoni", "Kohli", "Tendulkar"]
console.log(cricketers.shift());
// 'Dhoni'
console.log(cricketers);
// [ 'Kohli', 'Tendulkar' ]

Array.unshift()

This method will append element(s) to the left side of the Array.

Unlike push() which will append elements to the right side. You may use this method when you want to append elements to the beginning of the Array!

const cricketers = ["Bradman", "Lara"]
console.log(cricketers.unshift("Dhoni", "Kohli", "Tendulkar"))
// Output: 5 
// It's the new length of the Array
console.log(cricketers);
// Output: [ 'Dhoni', 'Kohli', 'Tendulkar', 'Bradman', 'Lara' ]

Array.sort()

Although some of you may know about the sort method. We will be looking at it in depth this time and understand how it works internally. Because the sort method in JavaScript works quite differently compared to other programming languages.

The sort method sorts the Array in ascending order (default) and then returns the same Array modified.

But it isn't that simple, if you try to sort an Array of numbers

console.log([43, 67, 49, 23, 32].sort())
// Output: [ 23, 32, 43, 49, 67 ]

This works fine! However, let's do it with big numbers.

console.log([430, 673, 4933, 230, 132, 44, 4].sort())
// Output: [ 132, 230, 4, 430,  44, 4933, 673 ]

What just happened here!? Why did the sort method return the array in random order? Is this a glitch?

This is not a glitch. Rather, JavaScript's Array.sort() works quite differently when sorting the elements.

Also, there is no parameter to specify if you want to sort the Array in descending order. You will have to pass a callback function for it. We will look at how that works

How Array.sort works?

We are assuming that we are sorting elements in ascending order.

The default behaviour of the sort method is such:

  • First, it will convert the elements into strings

  • Then, it will compare it based on that element's character code units

    Here the sort method is taking character codes of UTF-16

  • It will compare the sequences of the character codes of two elements

    Based on which element's character code unit sequence is larger, it will be sorted and put first in the Array sequence

  • Finally, it sorts the 2 elements in place

This is how the internal sorting logic of Array.sort works() because it is comparing it using their character codes and not the number itself.

If you look at the UTF-16 table and see the character codes for strings, a character code unit of '2' is 50 and for '4' it is 52

So, the character code of '230' would be 50 51 48 and of '4' it would be just 52

The sorting logic would compare the 50 of 50 51 48 against 52 Here 50 is smaller than 52 hence it will mark '230' as smaller than '4'.

Why did it not compare or take into account the 51 48? It will only do so when the previous unit is the same as the other element. If it was 52 vs 52 then it will compare the next sequence unit i.e 51 against 52

How Array.sort compares two elements

We are assuming that we are sorting elements in ascending order.

Array.sort() takes a callback function in which you can define a customized logic of how the function should sort elements. By default, the callback function is comparing the elements to sort them into ascending order.

The sort function expects 1 of the 3 values below in return from the callback function, which helps it to determine how to sort the current two elements.

  • -1 or < -1: It means that element B is greater than element A and hence no sorting is required

  • 0: It means that both elements A and B are the same, hence no sorting is required

  • 1 or > 1: It means that element A is greater than element B, hence sorting is required, so element B will be put before element A and then iteration will continue with element A

So, the callback function must return either 0, 1 or > 1 or -1 or < -1 to help the sort method know whether to sort or not.

Usually, you would subtract element B from A if you want to sort the numerical elements in ascending order. If A-B returns a negative number, means B is greater than A, hence no sorting is required.

Similarly to sort numerical elements in descending order you will subtract A from B (B-A)

Let's take a look at a few examples!

console.log([430, 673, 4933, 230, 132, 44, 4].sort( (a, b) => a - b ))
// Output: [4, 44, 132, 230, 430, 673, 4933]
// Sorted in ascending order ^^

console.log([430, 673, 4933, 230, 132, 44, 4].sort( (a, b) => b - a ))
// Output: [4933, 673, 430, 230, 132, 44, 4]
// Sorted in descending order ^^

Sorting Arrays of objects!


const batsmans = [
    {
        "runs": 45,
        "balls": 23,
        "wickets": 2,
    },
    {
        "runs": 56,
        "balls": 21,
        "wickets": 6,
    },
    {
        "runs": 56,
        "balls": 21,
        "wickets": 3,
    },
    {
        "runs": 34,
        "balls": 24,
        "wickets": 4,
    },
    {
        "runs": 74,
        "balls": 43,
        "wickets": 7,
    }

]
console.log(batsmans.sort((a, b) => a.runs - b.runs));
/*
Output:
[
  { runs: 34, balls: 24, wickets: 4 },
  { runs: 45, balls: 23, wickets: 2 },
  { runs: 56, balls: 21, wickets: 6 },
  { runs: 56, balls: 21, wickets: 3 },
  { runs: 74, balls: 43, wickets: 7 }
]
*/

Sorting by multiple parameters of an element

Let's say that you are sorting a list of batsmen based on their runs, in case their runs are the same, then you will sort it by balls but in descending order! In case the balls are also the same then you will sort by wickets lost (in descending order)

Take a look at this example!

const batsmans = [
    {
        "runs": 45,
        "balls": 23,
        "wickets": 2,
    },
    {
        "runs": 56,
        "balls": 21,
        "wickets": 6,
    },
    {
        "runs": 56,
        "balls": 21,
        "wickets": 3,
    },
    {
        "runs": 45,
        "balls": 43,
        "wickets": 7,
    }

]
console.log(batsmans.sort((a, b) => b.runs - a.runs || a.balls - b.balls || a.wickets - b.wickets));
/*
Output:
[
  { runs: 56, balls: 21, wickets: 3 },
  { runs: 56, balls: 21, wickets: 6 },
  { runs: 45, balls: 23, wickets: 2 },
  { runs: 45, balls: 43, wickets: 7 }
]
*/

Conclusion

We took a look at 11 lesser-known JavaScript Array methods that make working with Arrays and manipulating them easier! JavaScript works quite differently compared to other languages, this is why we took an in-depth look at how Array.sort() works and why it works in such a way. Technically this method has given us more power in how we want to sort our elements. Try to explore these methods and see how you can use them in your applications more effectively. Knowing and working with these methods brings you 1 step closer to being a great JavaScript developer!

The End!

If you have made it to the end of this article, Thank you so much for reading! ๐Ÿ’

ย