JavaScript Array Methods
Learning outcomes:
- Joining arrays together using
concat()
- Filling an array using
fill()
- Using
slice()
to slice an array - Adding/removing elements at the end —
push()
andpop()
- Adding/removing elements at the start —
unshift()
andshift()
- Adding/removing elements at an arbitrary index —
splice()
- Reversing an array using
reverse()
- Finding the index of an element using
indexOf()
andlastIndexOf()
- Existential and universal quantification using
some()
andevery()
- Filtering items via
filter()
- Joining array elements using
join()
- Mapping to a new array via
map()
Introduction
Arrays are highly useful for storing ordered collections of data but not until they are blended together with some useful methods.
In this chapter, we shall get an overview of the most fascinating methods available to all array instances in JavaScript.
Joining multiple arrays together
To join — or better to say, concatenate — two or more arrays together into a single array, we use the concat()
method.
Call it on a given array whose elements you want to appear first in the final array and then pass the rest of the arrays one by one, as arguments.
Something as follows:
arr1.concat(arr2, arr3, ...., arrN)
The order in which the arrays appear in the expression above is exactly the same order in which their elements are laid out in the final array.
concat()
method does NOT modify the original array; instead, it returns a new array composed of all the individual arrays together.Let's say we have three different lists of numbers which represent the marks of three different students in recent exams out of 100:
let a = [75, 54, 70],
let b = [94, 60, 78];
let c = [67, 80, 81];
Now we would like to collect all these marks in one, single array and then display them in sorted format.
For this we'll need to first join all the three arrays together and then perform the sorting on the final array obtained in the end. In the code below, we accomplish this idea using concat()
and finally log the resulting array:
let a = [75, 54, 70];
let b = [94, 60, 78];
let c = [67, 80, 81];
let allNums = a.concat(b, c);
console.log(allNums.sort(function(a, b) { return a - b; }));
[54, 60, 67, 70, 75, 78, 80, 81, 94]
Filling an array
If we wish to set each element of an array to the same value, we could iterate over it and assign each index that very value. An example follows:
// Fill array `arr` with value `v`
for (let i = 0; i < arr.length; i++) {
arr[i] = v;
}
Fortunately, there's a much easier way — use the fill()
array method.
Just pass fill()
the value to fill the given array with:
arr.fill(value)
The return value of fill()
is the filled array. Note that fill()
mutates the original array (and then returns it).
fill()
: one that allows us to specify the starting point, and one that allows us to specify both the starting and the ending point for the filling operation.Consider the examples below:
[1, 2, 3, 4].fill(0)
[0, 0, 0, 0]
[1, true, Infinity].fill(100)
[100, 100, 100]
If the array is empty, there won't be any consequence of calling fill()
on it, as can be seen below:
[].fill(0)
One of the most common applications of fill()
is to pre-initialize a sparse array, as we learned in the passing by in the last chapter.
The idea is to first create an array using new Array(n)
with n
empty spaces in it and then fill each of those empty slots with a given value using fill()
.
This is extremely handy when we have to work with a preinitialized array, where otherwise creating the array manually using literals would be quite a strenuous activity.
Let's take an example.
Suppose we have to create an array holding 100 values, each initialized to 0
. As you would agree, creating this array literally would be quite a difficult and error-prone task.
A better way would be to create an array to the desired length using new Array(100)
and then fill it with the value 0
. Something as follows:
let nums = new Array(100).fill(0);
console.log(arr[0]);
console.log(arr[50]);
console.log(arr[99]);
0
0
Voila! All of the three elements inspected are equal to 0
.
fill()
on it, the array returned by new Array(n)
consists of empty slots, accessing which would yield undefined
.Slicing an array
To extract out a given subarray from an array, we could use the slice()
method.
The slice()
method takes a starting (inclusive) and ending (exclusive) index and returns a slice of the array, i.e. a subarray, in that range.
Shown below is its syntax:
arr.slice([start[, end]])
As per the syntax, both start
and end
are optional (hence, the brackets around them):
start
specifies the index where to start the slicing. This is inclusive, and defaults to0
.end
specifies the index where to end the slicing. This is exclusive, and defaults toarr.length
.
slice()
method, with exactly the same syntax of arguments, for strings back in the JavaScript String Methods chapter.Let's consider a couple of examples:
let nums = [1, 2, 3, 4, 5];
console.log(nums.slice(0, 0)); // []
console.log(nums.slice(0, 1)); // [1]
console.log(nums.slice(1, 4)); // [2, 3, 4]
In the first slice()
statement, calling slice(0, 0)
returns an empty array because the slicing begins at 0
and ends right before 0
(at -1
).
In the second statement, calling slice(0, 1)
returns the array [1]
by beginning slicing at index 0
and ending it just before 1
(i.e. 0
).
In the last statement, calling slice(1, 4)
returns the array [2, 3, 4]
because slicing this time begins at index 1
and ends just before index 4
. This accounts for the indexes 1
, 2
and 3
(4
being exclusive).
Figure out the return value of nums.slice()
for the nums
array above.
Keep in mind the default values of both the start
and end
arguments.
undefined
[]
[1, 2, 3, 4]
slice()
is called without any arguments, the slice beings at index 0 and ends at the length of the array, i.e. it spans the entire array. This effectively means to slice the entire array and this goes with choice (C).Adding/removing elements at the end
As we saw in the previous chapter, to add an element, or a set of elements, at the end of an array, we could use the push()
method.
push()
method adds an element to the end of an array.The syntax is pretty straightforward:
arr.push(item1, item2, ..., itemN)
item1
, item2
, all the way to itemN
, represent items to be added to the array in that very order.
push()
mutates the original array and, therefore, changes the length of the calling array.Let's use push()
to add a couple of elements to an array:
let nums = [1, 2];
nums.push(3);
console.log(nums);
nums.push(4);
console.log(nums);
[1, 2, 3]
[1, 2, 3, 4]
In a similar way that we could add an element to the end of an array, we could remove it from there as well. For this, we have the pop()
method.
pop()
method removes an element from the end of an array.Since pop()
merely removes the last element from an array, it doesn't require any arguments:
arr.pop()
pop()
returns the element removed. This is useful because, often times, we have to use the value in the program before removing it.
Following from the last code, let's remove the last two elements using pop()
:
let nums = [1, 2];
nums.push(3);
nums.push(4);
console.log(nums);
console.log('Removing', nums.pop());
console.log('Removing', nums.pop());
console.log(nums);
[1, 2, 3, 4]
Removing 4
Removing 3
[1, 2]
Simple, wasn't it?
Adding/removing elements at the start
As we saw just right now, push()
and pop()
serve to add and remove stuff from the end of a given array. In JavaScript, and most programming languages that support dynamic arrays, we could do so at the start of the array as well.
The methods used in this case are unshift()
and shift()
.
unshift()
method adds an element to the start of an array.Parameter-wise, it's same as push()
:
arr.unshift(item1, item2, ..., itemN)
The given arguments are added to the start of arr
. Simple.
Let's consider a quick example:
let nums = [1, 2];
nums.unshift(3);
console.log(nums);
nums.unshift(4);
console.log(nums);
[3, 1, 2]
[4, 3, 1, 2]
To remove an element from the start of an array, we use the shift()
method.
shift()
method removes an element from the start of an array.It's syntactically the same as pop()
:
arr.shift()
The return value of shift()
is the element removed.
Let's consider a quick example following from the last code snippet above:
let nums = [1, 2];
nums.unshift(3);
nums.unshift(4);
console.log(nums);
console.log('Removing', nums.shift());
console.log('Removing', nums.shift());
console.log(nums);
[4, 3, 1, 2]
Removing 4
Removing 3
[1, 2]
Adding/removing elements at arbitrary indexes
To add and/or remove stuff from an array starting at an arbitrary index, instead of the beginning or end of the array, we have the splice()
method at our dispense.
splice()
is meant to add/remove elements from an array, in-place, starting from a given index.Note that splice()
mutates the original array.
Here's its syntax:
arr.splice([index[, deleteCount[, item1[, item2[, ...[, itemN]]]]]])
index
is the index where to begin the addition and/or removal of stuff. It can also be negative, in which case it's taken to be relative from the end of the array. It defaults to0
.deleteCount
specifies the number of items to delete starting from the positionindex
. Ifindex
is not specified, i.e.splice()
is called without any arguments,deleteCount
is0
. Otherwise, it is set toarr.length - index
, i.e. removes all elements upto the end of the array, starting fromindex
.item1
,item2
, all the wayitemN
, specify the elements to add atindex
. If omitted, nothing is added.
The return value of splice()
is an array holding the deleted items of the main array. If nothing is deleted, i.e. deleteCount
is 0
, an empty array is returned.
Time for some examples...
Let's say we have the following array and want to remove the second element from it:
let nums = [1, 50, -6, -20, 22];
How would we do so?
- Well, the second element is at index 1, and this is the position where the removal should begin; hence the first
index
arg tosplice()
becomes1
. - Moving on, since only one element is to be deleted,
deleteCount
would also be1
. - And finally, because nothing ought to be added, no args follow along.
Below, we perform the removal, and log both nums
and the array holding the removed item:
let nums = [1, 50, -6, -20, 22];
let deletedNums = nums.splice(1, 1);
console.log(nums);
console.log(deletedNums);
[1, -6, -20, 22]
[50]
See how the deleted element 50
is accessible as an element of deletedNums
.
In a real-world application, you might want to work with the set of removed items and that's where the return value of splice()
could help.
Let's see a couple more examples.
Say we have to delete the second last element from an array arr
. What would the set of args to splice()
be?
Simple — nums.splice(-2, 1)
.
An illustration follows:
let nums = [1, 50, -6, -20, 22];
let deletedNums = nums.splice(-2, 1);
console.log(nums);
console.log(deletedNums);
[1, 50, -6, 22]
[-20]
What if we want to remove nothing from an array, but rather add two elements at the second position? Hmm..
We'll call nums.splice(1, 0, ele1, ele2)
.
- We need to operate on the second position in the array, hence the first argument
1
. - Moreover, we wish to remove nothing from this position, hence the second argument
0
(which specifies the number of items to delete). - Finally, we wish to add two elements, hence the subsequent two arguments.
An illustration follows:
let nums = [1, 50, -6, -20, 22];
let deletedNums = nums.splice(1, 0, Infinity, NaN);
console.log(nums);
console.log(deletedNums);
[1, Infinity, NaN, 50, -6, -20, 22]
[]
Since nothing is removed in the array nums
above, splice()
returns an empty array.
splice()
without any arguments
Calling splice()
without any arguments has no effect on the given array and returns an empty array itself (since nothing is deleted in this case):
let nums = [1, 2, 3];
console.log(nums);
console.log(nums.splice());
[1, 2, 3]
[]
Reversing an array
Want to reverse the order of elements of an array? Well, for this you need the reverse()
method.
It's very simple in nature:
arr.reverse()
Note that as with sort()
, reverse()
mutates the original array and returns it back too.
Shown below is an example:
let subs = ["Chemistry", "Physics", "Math"];
console.log(subs.reverse());
console.log(subs);
['Math', 'Physics', 'Chemistry']
['Math', 'Physics', 'Chemistry']
In the first log statement, the reverse()
method returns back the reversed version of subs
and this is logged to the console. The second log statement outputs the same array as before. This confirms that the original array subs
was mutated by subs.reverse()
.
reverse()
method on that copy.Finding the index of an element
Do you recall the indexOf()
and lastIndexOf()
methods all the way back from the JavaScript String Methods chapter?
Both of these methods are available on array instances as well and serve a similar purpose — to return the index of a given element, if found.
The best part is that they're identical syntactically, so I won't be going over their syntax again here.
Shown below are a couple of examples of indexOf()
:
[1, 2, 3, 4].indexOf(1)
0
[1, 2, 3, 4].indexOf(4)
3
[1, 2, 3, 4].indexOf(5)
-1
[1, 2, 3, 4].indexOf("1")
-1
[1, true, true, false].indexOf(true)
1
Similar to indexOf()
, which finds the first match for a given value, the lastIndexOf()
method finds the index of the last match of a given value.
Consider the snippet below:
[1, 2, 3, 4].lastIndexOf(1)
0
[1, 2, 3, 4].lastIndexOf(4)
3
[1, 2, 3, 4].lastIndexOf(5)
-1
[1, 2, 3, 4].lastIndexOf("1")
-1
[1, true, true, false].lastIndexOf(true)
2
[1, 1, 0, 1].lastIndexOf(1)
3
Existential and universal quantification
In elementary logic, specifically in predicate logic, there is this idea of some item in a given set of items meeting a certain condition. We call this existential quantification.
A similar idea is that of universal quantification, where every single item meets the given condition.
These ideas of checking whether in a set of items, at least one or all elements meet a certain condition are present in JavaScript arrays as well. They are exposed by the some()
and every()
methods, respectively.
some()
takes a function and returns true
if the function evaluates to true
for at least one element in the calling array.Time to see its syntax:
arr.some(callbackFn)
callbackFn
is a function that is run for every element of arr
until it returns a truthy value. Here's the syntax of the callback function:
callbackFn(element, index, arr)
element
is the element ofarr
currently under inspection.index
is the index ofelement
.arr
holds a reference to original array.
Let's consider a quick example.
Say we want to confirm whether in a list of numbers there is at least one square number. We could solve this by laying out the callback function as follows:
function isSquare(element) {
return Number.isInteger(element ** 0.5);
}
If any one element in the list of numbers is a square, isSquare()
would return true
for it and hence cause some()
to return true
as well.
Shown below are a couple of examples:
function isSquare(element) {
return Number.isInteger(element ** 0.5);
}
let nums = [1, 2, 3];
console.log(`Square in ${nums}`, nums.some(isSquare));
nums = [2, 3, 4];
console.log(`Square in ${nums}`, nums.some(isSquare));
nums = [2, 3, 5, 7];
console.log(`Square in ${nums}`, nums.some(isSquare));
nums = [2, 3, 5, 7, 49, 100];
console.log(`Square in ${nums}`, nums.some(isSquare));
Square in 2,3,4: true
Square in 2,3,5,7: false
Square in 2,3,5,7,49,100: true
Following from the fact that for some()
to return true
, there has to be at least one element in the array for which the callback function returns true
, when the array is empty i.e. has not elements, some()
returns false
.
Consider the following code:
function isSquare(element) {
return Number.isInteger(element ** 0.5);
}
console.log([].some(isSquare));
In the same way, to check whether every single element in an array meets a given condition, we could use the every()
method.
every()
takes a function and returns true
if the function evaluates to true for every single element in the calling array, or otherwise false
.It's syntactically identical to some()
:
arr.every(callbackFn)
Check out the syntax for callbackFn
above.
The main difference is that the given callback function is run for every element in the given array and if, for any one, it returns a falsey value, every()
returns false
as well. It's only when the function returns a truthy value for every element in the array that every()
returns true
.
Let's say we want to confirm whether a student passed in all exams. The passing marks are above 50
. If the student's marks were modeled by an array marks
, we could use every()
to solve this task.
Shown below is an illustration:
function above50(marks) {
return marks >= 50;
}
let marksList = [35, 80, 54, 90, 60];
console.log(marksList.every(above50));
marksList = [78, 86, 70, 95, 71];
console.log(marksList.every(above50));
true
Following from the fact that for every()
to return false
, there has to be at least one element in the array for which the callback function returns false
, when the array is empty i.e. has not elements, every()
returns true
.
Consider the following code:
function above50(marks) {
return marks >= 50;
}
console.log([].every(above50));
Filtering elements
To obtain only those elements from an array that meet a given condition, we use the filter()
method.
filter()
takes in a callback function and returns an array containing all the elements in the calling array for which the callback function returns a truthy value.
arr.filter(callbackFn)
The syntax of this callback is the same as the one provided to the some()
and every()
methods discussed above. That is:
callbackFn(element, index, arr)
where element
is the current element under consideration, index
is its index in the array, and arr
is the array.
If you think for a second, the word 'filter' is quite a sensible name for this method. It says to 'filter in' elements from an array based on a given condition.
filter()
specifies which elements we are interested in, NOT those elements that we wish to filter out, i.e. ignore.Pretty clever naming!
Say we want to extract out all positive values from an array of numbers. For this we'll set up the callback function as follows:
function positiveNumber(num) {
return num > 0;
}
This would return true
only for those numbers that are greater than 0
. Let's use this function along with filter()
on a couple of arrays and see the outcome in each case:
function positiveNumber(num) {
return num > 0;
}
let nums = [10, 5, -4, -1, 50, 34, -27];
console.log(nums.filter(positiveNumber));
nums = [0, 15, 0, -6, -1, -4, -0.5, 3.1, 10.5];
console.log(nums.filter(positiveNumber));
[10, 5, 50, 34]
[15, 3.1, 10.5]
filter()
method is no doubt very quick and concise.Create an array evens
by filtering out all the even-indexed elements from the following nums
array:
let nums = [1, 10, 5, 33, 198, 0, 5, 8];
Your evens
array shall be equal to [1, 5, 198, 5]
as these elements have even indexes in nums
— 0
, 2
, 4
, and 6
respectively.
Think of the second parameter of the callback function passed to filter()
.
let nums = [1, 10, 5, 33, 198, 0, 5, 8];
let evens = nums.filter(function(e, i) {
return i % 2 === 0;
});
Joining elements together
When working with arrays, it's extremely common to go into a string representation by joining the individual elements together.
If we just want to join the elements with a comma in betweeen, we can call the toString()
method or even just use the array in the context of a string, e.g. in a string concatenation operation.
Both of these are shown below:
[1, 2, 3, 4].toString()
'1,2,3,4'
[1, 2, 3, 4] + ''
'1,2,3,4'
'The numbers are: ' + [1, 2, 3, 4]
'The numbers are: 1,2,3,4'
This joins the array elements with a comma (,
) in between, without any space around it. However, if we want a different separator, then we need to use the join()
method.
join()
accepts an optional, string argument which is the separator to put in between the array's elements:
arr.join([separator])
By default, separator
is set to ','
, which means that arr.join()
is effectively the same as calling arr.toString()
.
The return value of the join()
method is a string containing all elements of arr
separated by separator
.
In the code below, we create an array nums
and then output it with each element being separated from the other one using a space:
let nums = [1, 2, 10, 50, 100];
console.log(nums.join(' '));
Mapping an array
It's a common idea to iterate over an array and map each of its elements onto a new element. These mapped elements are put in a new array.
For instance, suppose we have a list of positive integers. We could create a list of squares out of it by mapping each integer to the square of that integer. Similarly, we could even obtain a list of cubes.
In JavaScript, we use the map()
method to create a new array based on a given array, with a mapping function.
map()
method takes a function and returns a new array comprised of elements returned by the function for each element of the calling array.In its simplest form, we just ought to provide the mapping function to map()
, that's it:
arr.map(mappingFn)
Let's now talk about the syntax of this mapping function, mappingFn
. It's similar to the callback function provided to some()
, every()
, and filter()
.
mappingFn(element, index, arr)
element
is the element ofarr
currently under inspection.index
is the index of thiselement
.arr
holds a reference to the array in question.
Let's consider a couple of examples...
Below we have an array ints
which is used to create two more arrays squares
and cubes
by means of square and cube functions, respectively:
function square(int) { return int ** 2 };
function cube(int) { return int ** 3 };
let ints = [0, 1, 2, 3, 4, 5];
let squares = ints.map(square);
console.log(squares);
let cubes = ints.map(cube);
console.log(cubes);
// Let's see if `ints` has been modified
console.log(ints);
[0, 1, 4, 9, 16, 25]
[0, 1, 8, 27, 64, 125]
[0, 1, 2, 3, 4, 5]
The last log here confirms the fact that calling map()
on an array does not mutate it.
Going ahead, a common practice you'll see in coding competitions out there is to use this notion of mapping to convert a list of stringified numbers into a list of numbers.
In the code below, we convert a string of space-delimited numbers into an array of numbers using a couple of handy methods, including map()
:
let str = '10 -5 40 1 0 0 3';
let nums = str.split(' ').map(Number);
console.log(nums);
[10, -5, 40, 1, 0, 0, 3]
Time to understand what's happening over here...
str.split(' ')
breaks apart str
at each space (' '
) character and returns back an array of the left-over strings, as follows:
str.split(' ')
['10', '-5', '40', '1', '0', '0', '3']
Next up, map(Number)
goes over this array of strings and runs the Number()
function over each string. Recall that, given an argument, Number()
converts it into a number.
['10', '-5', '40', '1', '0', '0', '3'].map(Number)
[10, -5, 40, 1, 0, 0, 3]
All in all, this is an elegant way to convert a string of numbers into an array of numbers, without having to spin up a complex piece of code containing a loop.
Spread the word
Think that the content was awesome? Share it with your friends!
Join the community
Can't understand something related to the content? Get help from the community.