Introduction
When working with any programming language, you'll probably need some functionality that is not integrated into that language natively. Thus, you'll either implement them yourself, or turn to using various modules or libraries.
This directly affects the efficiency of your application (more memory usage, more HTTP requests, etc.). To avoid this, developers working on advancing programming languages have integrated functions within the languages to help avoid having to use external libraries for common tasks.
Getting acquainted with these built-in functions is considered fundamental knowledge of a language, and you can still get pretty far with just the built-in functions. Of course, you'll most likely end up using some modules/libraries for certain tasks.
In this beginner-oriented guide, we'll take a look at the built-in functions of JavaScript pertaining to Arrays.
JavaScript's Data Types, Structures and Objects with Built-in Functions
In JavaScript, there are eight data types:
- String
- Number
- Boolean
- Null
- Undefined
- Symbol
- BigInt
- Object
However, not every data type has a built-in function. They're only defined on: String, Number and Boolean.
When it comes to Data Structures in JavaScript, the seven most used structures are:
- Array
- Stack
- Queue
- Linked List
- Tree
- Graph
- Hashtable
Similar to data types, in Data Structures, built-in functions are only defined on an Array. Finally, Objects in JavaScript also have built-in functions, such as Date, RegExp and Math.
In this guide, we'll be focusing on Arrays specifically.
Built-in String Functions in JavaScript
An Array in JavaScript is a global, list-like object. It is used to store data of various types. JavaScript's Array elements don't have to be of the same type, they can be arbitrary. This property of list-like data structures is also known as heterogeneity - arrays are heterogeneous.
Arrays are index-based, starting at 0
, which is a standard implementation across various programming languages:
let myArray1 = [x1, x2, ... , xN];
let myArray2 = new Array(x1, x2, ... , xN);
let myArray3 = Array(x1, x2, ... , xN);
Given how commonly arrays are used in day-to-day work, getting acquainted with the functions used to add, remove and otherwise process or manipulate the elements within them is considered fundamental knowledge.
If you'd like to read more about JavaScript collections in general, read our Guide to Getting Started with Collections in JavaScript!
push()
The push(element)
function adds new element
to the end of the array:
let array = [1, 2, 3, 4];
array.push(5);
console.log(array); // Output: [1, 2, 3, 4, 5]
Typically, the push()
action is associated with stacks and queues - not arrays, though, in JavaScript's implementation - this operation is dubbed push()
.
Why?
Arrays are meant to be as generic as possible and you can actually use an array to implement a Queue
or Stack
in JavaScript, as these are not built-in types, and you'll have to implement them yourself or use an external library.
Merging Arrays with push()
Additionally, using the push()
function alongside the spread operator, you can merge multiple arrays together:
let array1 = [1, 2, 3, 4];
let array2 = [5, 6, 7, 8]
array1.push(...array2);
console.log(array1); // Output: [ 1, 2, 3, 4, 5, 6, 7, 8 ]
pop()
pop()
can be used to remove the last element of an array. Alongside push()
, pop()
is one of the three integral methods used to implement queues and stacks, and can be used outside of that context as well:
let array = [1, 2, 3, 4];
let x = array.pop();
console.log(x); // Output: 4
console.log(array); // Output: [1, 2, 3]
The pop()
function returns the popped element, so you can reuse it for any other purpose. For instance, you can pop()
elements straight into a new array or other data structure, or save it to the database.
shift()
shift()
removes the first element from an array and returns it - essentially opposite of pop()
. With these three, you can implement FIFO (First-In-First-Out) and LIFO (Last-In-First-Out) structures:
let array = [1, 2, 3];
let x = array.shift();
console.log(x); // Output: 1
console.log(array); // Output: [2, 3]
sort()
The sort()
function sorts the elements of an array, based on their natural, ascending order.
What's the natural order?
Depending on the data type - the natural order entails different meanings. For Number
instances, they can be compared via the <
, >
and similar comparison operators. Strings are compared alphabetically.
Heterogeneous arrays are sorted in batches - elements of type
Number
are sorted, followed by elements of typeString
, followed by custom objects.
It's worth noting that sort()
sorts the array in-place, changing the original array so if you'd like to keep the original as well - you have to perform a deep copy, and not just keep a reference, as the reference will point to the changed array as well:
let array1 = [1, 3, 2, 0];
let array2 = ["JavaScript", "Java", "Python"];
let array3 = ["b", 3, 1, "c", "a"];
let originalArray1 = [...array1];
console.log('Sorted array1:', array1.sort());
console.log('Sorted array2:', array2.sort());
console.log('Sorted array3:', array3.sort());
console.log('Original array1:', originalArray1);
This results in:
Sorted array1: [ 0, 1, 2, 3 ]
Sorted array2: [ 'Java', 'JavaScript', 'Python' ]
Sorted array3: [ 1, 3, 'a', 'b', 'c' ]
Original array1: [ 1, 3, 2, 0 ]
You can also supply a sorting function with your own implementation to the sort()
function, overriding the default behavior. The function should accept two arguments, and return 1
, 0
or -1
based on their comparison.
If the first value is lesser than the second, 1
is returned. If the first value is greater than the second -1
is returned. If they're equal, 0
is returned.
Based on this
- If the function returns a value greater 0 - the second element is sorted before the first.
- If the function returns a value lesser than 0 - the first element is sorted before the second.
- If the function returns 0 - these are equal and keep their relative order.
Let's implement a custom function that sorts strings in reverse order, instead of alphabetically. To achieve this - we'll switch around the returned values so that 1
is returned if the first value is greater than the second, instead of the other way around:
let array = ["JavaScript", "Java", "Python"];
console.log('Custom sort:', array.sort(customSort));
console.log('Default sort:', array.sort());
function customSort(a, b) {
if (a < b) {
return 1;
}
if (a > b) {
return -1;
}
return 0;
}
This results in:
Custom sort: [ 'Python', 'JavaScript', 'Java' ]
Default sort: [ 'Java', 'JavaScript', 'Python' ]
slice()
The slice(start, end)
function returns a part of the array between index value start
and index value end-1
. It by all means slices an array, and returns a new one, consisting of the elements.
The original array stays intact:
let array = [10, 20, 30, 40, 50];
let subarray = array.slice(2, 4);
console.log(array); // Output: [ 10, 20, 30, 40, 50 ]
console.log(subarray); // Output: [30, 40]
slice()
to arrays is what substring()
is to strings - and it's a really commonly used function to truncate or subarray certain sequences.
splice()
The splice(start, deleteCount, item)
function is used to replace and remove elements in an array, as well as insert them. Its bounds start at start
and remove deleteCount
elements, optionally replacing them with item
or multiple elements if supplied.
Additionally, it returns the removed elements, which you can then save if you'd like to:
let array = [10, 20, 30, 40, 50];
let splicedArray = array.splice(3, 2, 'newElement');
console.log('Spliced elements: ', splicedArray);
console.log('Changed array: ', array);
Here, the splice()
function starts at the 3rd element (0-based indexing), and removes the following two elements, replacing them with a single newElement
. The removed elements are saved in the splicedArray
array:
Spliced elements: [ 40, 50 ]
Changed array: [ 10, 20, 30, 'newElement' ]
Without the optional item
or multiple items, you can actually use splice()
somewhat similarly to slice()
, but at the same time, actually removing the elements from the array:
let array = [10, 20, 30, 40, 50];
let splicedArray = array.splice(3, 2);
console.log('Spliced elements: ', splicedArray);
console.log('Changed array: ', array);
Check out our hands-on, practical guide to learning Git, with best-practices, industry-accepted standards, and included cheat sheet. Stop Googling Git commands and actually learn it!
This results in:
Spliced elements: [ 40, 50 ]
Changed array: [ 10, 20, 30 ]
reverse()
reverse()
, as the name suggests, reverses the order of elements in the array:
let array = [1, 2, 3];
console.log(array.reverse()) // Output: [3, 2, 1]
Note: The reverse() method reverses the array in-place. This means that the original num_array and string_array are reversed and the original sequence is lost.
Even though it's done in-place, it's still common to "assign" the result of the operation to a new variable, to at least denote a reversed array:
let array = [1, 2, 3];
let arrayReversed = array.reverse();
console.log(arrayReversed ) // Output: [3, 2, 1]
map()
The map(f)
function applies the function f
to a copy of every element of the array. This function is really useful when you'd like to, well, map elements to a different collection, such as users to their IDs or elements to a category:
let array = ["Java", "Python", "JavaScript"];
let langLengths = array.map(function(x){
return x.length;
});
console.log(langLengths);
In this code snippet, we map the length of each string in the list, producing:
[ 4, 6, 10 ]
If you'd like to include the language names next to their lengths, you'll want to store the results in a dictionary, that can hold key-value pairs:
let array = ["Java", "Python", "JavaScript"];
let mapping = Object.assign({}, ...array.map((x) => ({[x]: x.length})));
console.log(mapping);
This results in:
{ Java: 4, Python: 6, JavaScript: 10 }
forEach()
forEach(f)
applies the function f
for each element of the array. The difference between map
and forEach
is that map
creates a new array and doesn't change the original one, while forEach
changes the original.
let languageArray = ["Java", "JavaScript", "Python"];
console.log("Printing each element: \n______");
// Print each element
languageArray.forEach(element => console.log(element));
console.log("\nPrinting each element in uppercase: \n______");
// Print uppercase version of each element, while keeping original strings intact
languageArray.forEach(element => console.log(element.toUpperCase()));
// Change the original array, changing all elements to lowercase
languageArray.forEach(function(element, index, array){
array[index] = array[index].toLowerCase();
});
console.log("\nEach element converted to lowercase: \n______");
console.log(languageArray);
The element
needs to be defined even if you're not using it, such as in the last example. These result in:
Printing each element:
______
Java
JavaScript
Python
Printing each element in uppercase:
______
JAVA
JAVASCRIPT
PYTHON
Each element converted to lowercase:
______
[ 'java', 'javascript', 'python' ]
join()
The join()
method joins all elements of an array into a string, converting the elements into string representations depending on their type. Numbers are easy to convert into strings but for custom objects, the toString()
method is called to return the string representation.
Additionally, when joining - the default separator is a comma, which produces a CSV-like format. However, you can define any character to be the separator instead just by passing it into the function.
Let's start off with simpler types:
let array = [1, 2, "hello"];
let str1 = array.join();
let str2 = array.join('');
let str3 = array.join('_');
console.log('Result: ', str1);
console.log('Result: ', str2);
console.log('Result: ', str3);
console.log('Type of result: ', typeof(str1));
Numbers are easily converted into strings, and joined based on the separator we've defined:
Result: 1,2,hello
Result: 12hello
Result: 1_2_hello
Type of result: string
When dealing with custom objects though, the conversion to a string will result in an object reference, unless a valid toString()
method is defined, which returns a string representation. In this case, let's define a User
class, with a toString()
that returns the name of the user:
class User {
/** @access private */
#name;
constructor(name){
this.#name = name;
}
getName() {
return this.#name;
}
setName(name) {
this.#name = name;
}
toString() {
return this.#name;
}
}
let john = new User("John");
let maria = new User("Maria");
let array = [john, maria, "hello"];
let str = array.join();
console.log('Result: ', str);
console.log(typeof('Type of result: ', str));
This results in:
Result: John,Maria,hello
Type of result: string
If you'd like to read more about classes and OOP in JavaScript, read our Guide to Understanding Classes in JavaScript.
every()
every(p)
returns true
if every element of the array satisfies the passed predicate p
.
A predicate is nothing but a function that accepts a variable, and returns
true
orfalse
.
To that end, you can easily create anonymous functions (or even explicit ones) that return a boolean value based on the variable you supply. For instance, you can check if every()
element in a list is greater than 0
or contains some value:
let simpleArray = [1, 2, 3];
console.log(simpleArray.every(x => x > 0)); // Output: true
let objectArray = [new User('John'), new User('Maria')];
console.log(objectArray.every(x => x.age > 21));
some()
some(p)
returns true if any element satisfies the passed predicate p
:
let a = [1, 2, 3];
console.log(a.some(x => x == 2)); // Output: true
filter()
filter(p)
returns a new array consisting of the elements satisfying the passed predicate p
. The elements that don't pass it (function returns false
) aren't included after the filtering:
let a = [1, 2, 3];
console.log(a.every(x => x > 1)); // Output: [2, 3]
indexOf() and lastIndexOf()
The indexOf()
and lastIndexOf()
functions accept an element, and if present in the array, return its index in the sequence. If not present - -1
is returned.
If multiple elements matching the provided one exist - only the index of the first one is returned:
let simpleArray = [1, 4, 5, 4, 5, 6, 5, 8];
console.log(simpleArray.indexOf(5));
console.log(simpleArray.indexOf(10));
This results in:
2
-1
Similarly, the lastIndexOf()
method iterates backwards, and returns the last occurrence, instead of the first occurrence of a matching element:
let simpleArray = [1, 4, 5, 4, 5, 6, 5, 8];
console.log(simpleArray.lastIndexOf(5));
console.log(simpleArray.lastIndexOf(10));
This results in:
6
-1
Additionally, you can supply an optional starting point for the lastIndexOf()
and indexOf()
functions, which are both 0-based:
let simpleArray = [1, 4, 5, 4, 5, 6, 5, 8];
console.log(simpleArray.lastIndexOf(5, 3));
console.log(simpleArray.indexOf(5, 5));
The lastIndexOf()
doesn't start at the end of the array - at element 8
. It starts at the element with the index of 3, which is the second element 4
in this array. The indexOf()
doesn't start at the beginning of the array, but at the element on the index of 5:
// ↓ lastIndexOf() start
let simpleArray = [1, 4, 5, 4, 5, 6, 5, 8];
// ↑ indexOf() start
Given the changes starting points, this results in:
2
6
Conclusion
In this guide, we've taken a look at some of the most commonly used built-in functions pertaining to Arrays in JavaScript. Given how prevalent Arrays are in day-to-day work - getting acquainted with these functions is a must for any new developer.