Arrays are one of the most commonly used data structures in JavaScript. It provides a lot of built-in methods to create, modify, search, and even transform arrays result.
In this article i covers most of array methods, with examples.
Table of Contents
- Creating Arrays
- Adding and Removing Elements
- Searching and Finding
- Iteration Methods
- Sorting and Reversing
- Joining and Flattening
- Copying and Filling
- Conversion
- Advanced Tips & Best Practices
- TL;DR
- References
1. Creating Arrays
Array.of(...items)
Creates a new array from the arguments. Arguments can be of any type.
const arr = Array.of(1, 2, 3);
console.log(arr); // [1, 2, 3]
Note:
of(5)
method is similar tonew Array(5)
. But the main difference isnew Array(5)
creates an empty array with length 5, whileof(5)
creates array with 5 length and all elements initialized toundefined
.
Array.from(items, mapFn?)
Creates a new array from an iterable or array-like object.
Also support execute a function on each element of the array.
// Convert string to array
console.log(Array.from("hello"));
// ["h", "e", "l", "l", "o"]
// Map function applied during creation
const doubled = Array.from([1, 2, 3], (x) => x * 2);
console.log(doubled); // [2, 4, 6]
Note:
.from
method is similar tomap()
. In more details,.from(obj, mapFn)
has the same result as .from(obj).map(mapFn)
, except that it does not create an intermediate array, andmapFn
only receives two arguments(element, index)
without the whole array, because the array is still under construction.
2. Adding and Removing Elements
push(...items)
Adds elements to the end of array and returns the new length of the array.
const fruits = ["apple"];
const arrLength = fruits.push("banana", "cherry"); // 3
console.log(fruits); // ["apple", "banana", "cherry"]
pop()
Remove last element and returns that element.
const fruits = ["apple", "banana"];
const lastElement = fruits.pop();
console.log(lastElement); // "banana"
console.log(fruits); // ["apple"]
unshift(...items)
Adds elements to the beginning of array and returns the new length of the array.
const arr = [2, 3];
arr.unshift(0, 1);
console.log(arr); // [0, 1, 2, 3]
shift()
Remove first element from array and returns the removed element.
const arr = [1, 2, 3];
const firstElement = arr.shift();
console.log(firstElement); // 1
console.log(arr); // [2, 3]
splice(start, deleteCount, ...items)
It changes the contents of array by removing or replacing existing elements and/or adding new elements in place
Example 1: Deleting Elements
To delete elements from array, only need to provide start
and deleteCount
arguments.
const fruits = ["apple", "banana", "cherry", "grape", "kiwi"];
// Remove 2 elements starting at index 2 ('cherry' and 'grape')
const removed = fruits.splice(2, 2);
console.log(fruits); // Output: ['apple', 'banana', 'kiwi']
console.log(removed); // Output: ['cherry', 'grape']
Example 2: Adding Elements
To add elements without removing any, set deleteCount
to 0
.
const colors = ["red", "green", "blue"];
// Add two new colors at index 1
colors.splice(1, 0, "yellow", "purple");
console.log(colors); // Output: ['red', 'yellow', 'purple', 'green', 'blue']
Example 3: Replacing Elements
To replace elements, provide a deleteCount
greater than 0
and also specify items to add.
const letters = ["a", "b", "c", "d", "e"];
// Replace 2 elements starting at index 1 with 'x' and 'y'
letters.splice(1, 2, "x", "y");
console.log(letters); // Output: ['a', 'x', 'y', 'd', 'e']
Example 4: Negative Start Index
You can use a negative number for the start
index to count
from the end
of the array. -1
is the last element, -2
is the second-to-last, and so on.
const numbers = [10, 20, 30, 40, 50];
// Remove the last two elements
numbers.splice(-2, 2);
console.log(numbers); // Output: [10, 20, 30]
slice(start?, end?)
It returns a shallow copy of portion of array into a new array. And not modify the original array.
Example 1: Basic Slicing
To create a new array from specific range, you provide both start
and end
index.
const animals = ["ant", "bison", "camel", "duck", "elephant"];
// Extract elements from index 2 up to (but not including) index 4
const slicedAnimals = animals.slice(2, 4);
console.log(slicedAnimals); // Output: ['camel', 'duck']
console.log(animals); // Output: ['ant', 'bison', 'camel', 'duck', 'elephant']
Example 2: Slicing to the End of the Array
If you omit the end
argument, slice()
will extract all elements from the start
index to the end
of array.
const colors = ["red", "green", "blue", "yellow", "purple"];
// Extract from index 1 to the end
const remainingColors = colors.slice(1);
console.log(remainingColors); // Output: ['green', 'blue', 'yellow', 'purple']
Example 3: Negative Indexing
You can use negative numbers for both start
and end
to count
from the end
of array. -1
refers to the last element, -2
to the second-to-last, and so on.
const letters = ["a", "b", "c", "d", "e"];
// Extract the last two elements
const lastTwo = letters.slice(-2);
console.log(lastTwo); // Output: ['d', 'e']
// Extract elements from the third-to-last up to the last (not including it)
const middleSlice = letters.slice(-3, -1);
console.log(middleSlice); // Output: ['c', 'd']
3. Searching and Finding
indexOf(searchElement, fromIndex?)
Returns the first index at which a given element if exist in array
, or -1
if it is not present. It performs a strict equality comparison (===
) to find the element.
const fruits = ["apple", "banana", "cherry", "apple"];
const firstAppleIndex = fruits.indexOf("apple");
console.log(firstAppleIndex); // Output: 0
const orangeIndex = fruits.indexOf("orange");
console.log(orangeIndex); // Output: -1 (Not found)
const numbers = [10, 20, 30, 40, 50, 20];
// Find the first '20' starting from index 0
const first20 = numbers.indexOf(20);
console.log(first20); // Output: 1
// Find the next '20' starting from index 2
const second20 = numbers.indexOf(20, 2);
console.log(second20); // Output: 5
lastIndexOf(searchElement, fromIndex?)
Returns the last index of given element maybe exist in array, or -1
if it is not present. It performs a strict equality comparison (===
) to find the element.
const fruits = ["apple", "banana", "cherry", "apple", "banana"];
const lastBananaIndex = fruits.lastIndexOf("banana");
console.log(lastBananaIndex); // Output: 4
const firstBananaIndex = fruits.indexOf("banana");
console.log(firstBananaIndex); // Output: 1
const orangeIndex = fruits.lastIndexOf("orange");
console.log(orangeIndex); // Output: -1 (Not found)
includes(valueToFind, fromIndex?)
Determines whether array includes a certain value among its entries.
const fruits = ["apple", "banana", "cherry"];
console.log(fruits.includes("banana")); // Output: true
console.log(fruits.includes("grape")); // Output: false
const numbers = [10, 20, 30, 40, 50];
// Check if '40' is in the array starting from index 3
console.log(numbers.includes(40, 3)); // Output: true
// Check for '20' starting from index 2
console.log(numbers.includes(20, 2)); // Output: false (search starts at index 2)
A key advantage of
includes()
is its ability to findNaN
, whichindexOf()
cannot.
const numbersWithNaN = [1, 2, NaN];
console.log(numbersWithNaN.includes(NaN)); // Output: true
console.log(numbersWithNaN.indexOf(NaN)); // Output: -1
find(callback)
Returns the first element in array that satisfies a provided testing function. It return undefined
if no element passes the test.
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);
// Output: { id: 2, name: 'Bob' }
const missingUser = users.find((user) => user.id === 99);
console.log(missingUser);
// Output: undefined
findIndex(callback)
Returns the index of the first element that satisfies the provided testing function. t return -1
iIf no elements satisfy the testing function.
const users = [
{ id: 1, name: "Alice" },
{ id: 2, name: "Bob" },
{ id: 3, name: "Charlie" },
];
const bobIndex = users.findIndex((user) => user.name === "Bob");
console.log(bobIndex);
// Output: 1
const nonExistentIndex = users.findIndex((user) => user.name === "David");
console.log(nonExistentIndex);
// Output: -1
4. Iteration Methods
forEach(callback)
It used for performing an action on each item, but it doesn't create a new array or return a value.
const colors = ["red", "green", "blue"];
colors.forEach((color, index) => {
console.log(`Color at index ${index} is ${color}.`);
});
// Output:
// Color at index 0 is red.
// Color at index 1 is green.
// Color at index 2 is blue.
map(callback)
It creates a new array by calling a callback function on each element in the original array.
It's one of the most commonly used array methods because it allows you to transform an entire array's content without changing the original array.
const users = [
{ id: 1, name: "Alice" },
{ id: 2, name: "Bob" },
{ id: 3, name: "Charlie" },
];
// Creates a new array containing only the names
const userNames = users.map((user) => user.name);
console.log(userNames); // Output: ['Alice', 'Bob', 'Charlie']
filter(callback)
It creates a new array containing only elements from the original array that pass the test.
This is one of the most useful array methods for selecting or "filtering" a subset of data. The original array is not changed.
const users = [
{ name: "Alice", role: "admin" },
{ name: "Bob", role: "user" },
{ name: "Charlie", role: "admin" },
];
// Find all users with the 'admin' role
const admins = users.filter((user) => user.role === "admin");
console.log(admins);
/* Output:
[
{ name: 'Alice', role: 'admin' },
{ name: 'Charlie', role: 'admin' }
]
*/
reduce(callback, initialValue?)
It executes a function on each element of array, returning a single output value that can be number, string, object, or any other single value.
initialValue
A value used as the first argument to the first call of the callback. If not provide, the first element of the array is used as theinitialValue
and the iteration starts from the second element.
const pets = ["dog", "cat", "dog", "fish", "cat", "dog"];
const petCount = pets.reduce((acc, curr) => {
if (acc[curr]) {
acc[curr] += 1;
} else {
acc[curr] = 1;
}
return acc;
}, {});
console.log(petCount); // Output: { dog: 3, cat: 2, fish: 1 }
some(callback)
It checks if at least one element in array passes a test provided by a callback function.
const users = [
{ name: "Alice", role: "user" },
{ name: "Bob", role: "editor" },
{ name: "Charlie", role: "admin" },
];
const hasAdmin = users.some((user) => user.role === "admin");
console.log(hasAdmin); // Output: true
every(callback)
It checks if all elements in array pass a test provided by a callback function.
const users = [
{ name: "Alice", role: "admin" },
{ name: "Bob", role: "admin" },
{ name: "Charlie", role: "admin" },
];
// Check if all users have the 'admin' role
const allAreAdmins = users.every((user) => user.role === "admin");
console.log(allAreAdmins); // Output: true
5. Sorting and Reversing
sort(compareFn?)
Sorts the elements of array in place and returns the sorted array. The default sort order is ascending
By default,
sort()
treats everything as astring
.
const fruits = ["banana", "apple", "cherry"];
fruits.sort();
console.log(fruits); // Output: ['apple', 'banana', 'cherry']
This works great for strings. But, when used it with numbers:
const numbers = [10, 2, 5, 20];
numbers.sort();
console.log(numbers); // Output: [10, 2, 20, 5]
The output is [10, 2, 20, 5]
because the numbers are converted to strings: "10", "2", "5", "20". The string "1" comes before "2", so "10" comes before "2".
To sort numbers correctly, you must provide a compare function.
const numbers = [10, 2, 5, 20];
// Ascending sort
numbers.sort((a, b) => a - b);
console.log(numbers); // Output: [2, 5, 10, 20]
// Descending sort
numbers.sort((a, b) => b - a);
console.log(numbers); // Output: [20, 10, 5, 2]
The a - b
logic works because:
- If
a
is less thanb
,a - b
is negative, soa
comes first. - If
a
is greater thanb
, a - b is positive, sob
comes first.
You can sort array of objects based on a specific property using a compare function.
const users = [
{ name: "Bob", age: 30 },
{ name: "Charlie", age: 25 },
{ name: "Alice", age: 35 },
];
// Sort by age in ascending order
users.sort((a, b) => a.age - b.age);
console.log(users);
/* Output:
[
{ name: 'Charlie', age: 25 },
{ name: 'Bob', age: 30 },
{ name: 'Alice', age: 35 }
]
*/
reverse()
Reverses array and changes the original array so that the first element becomes the last, and the last element becomes the first.
const numbers = [1, 2, 3, 4, 5];
numbers.reverse();
console.log(numbers); // Output: [5, 4, 3, 2, 1]
6. Joining and Flattening
join(separator?)
Returns a new string by concatenating all the elements in array, separated by commas or a specified separator string.
// join array elements with a simple separator, like a space.
const greeting = ["Hello", "World"].join(" ");
console.log(greeting); // Output: "Hello World"
// join elements without any separation, you can pass an empty string ('') as the separator.
const letters = ["j", "a", "v", "a", "s", "c", "r", "i", "p", "t"];
const combined = letters.join("");
console.log(combined); // Output: "javascript"
flat(depth = 1)
Creates a new array with all sub-array elements concatenated into it recursively up to a specified depth. It's a simple and powerful way to "flatten" a nested array structure
const deepArray = [1, [2, [3, 4]]];
// Flatten only one level (default behavior)
const oneLevelFlat = deepArray.flat();
console.log(oneLevelFlat); // Output: [1, 2, [3, 4]]
// Flatten two levels
const twoLevelsFlat = deepArray.flat(2);
console.log(twoLevelsFlat); // Output: [1, 2, 3, 4]
If you are unsure of the nesting level, you can use
Infinity
to flatten all levels of a nested array.
flat()
automatically removes empty slots in array.
const emptySlots = [1, , 3, [4, 5]];
const filledIn = emptySlots.flat();
console.log(filledIn); // Output: [1, 3, 4, 5]
flatMap(callback)
Returns a new array formed by applying callback function to each element of array, and then flattening the result by one level. It is similar to a map()
followed by a flat()
of depth 1
(arr.map(...args).flat()
), to be honest it better than calling two methods separately.
const sentences = ["hello world", "how are you"];
// `map()` would return [['hello', 'world'], ['how', 'are', 'you']]
const words = sentences.flatMap((sentence) => sentence.split(" "));
console.log(words); // Output: ['hello', 'world', 'how', 'are', 'you']
Also can be used for both filter elements and transform the remaining elements.
If the mapping function returns empty array, it removed from the final flattened array.
const numbers = [1, 2, 3, 4];
// Filter out even numbers and double the odd ones.
// The empty array for even numbers results in no elements being added.
const doubledOddNumbers = numbers.flatMap((num) =>
num % 2 !== 0 ? [num * 2] : []
);
console.log(doubledOddNumbers); // Output: [2, 6]
7. Copying and Filling
fill(value, start = 0, end = length)
Changes all elements in array to a static value
, from a start index
to an end index
. Also modify the original array and returns the modified array
.
const fruits = ["apple", "banana", "cherry", "grape"];
// Fill with 'kiwi' starting at index 1 and ending before index 3
fruits.fill("kiwi", 1, 3);
console.log(fruits); // Output: ['apple', 'kiwi', 'kiwi', 'grape']
You can use negative indices for start
and end
to count
from the end of the array.
const letters = ["a", "b", "c", "d", "e"];
// Fill the last two elements with 'z'
letters.fill("z", -2);
console.log(letters); // Output: ['a', 'b', 'c', 'z', 'z']
copyWithin(target, start = 0, end = length)
It create a sequence of array elements within the same array. It overwrites existing elements, but it doesn't change the array's length.
const letters = ["a", "b", "c", "d", "e"];
// Copy elements from index 3 to the end ('d', 'e') to target index 0
letters.copyWithin(0, 3);
console.log(letters); // Output: ['d', 'e', 'c', 'd', 'e']
8. Conversion
toString()
Returns a string of array and its elements.
const fruits = ["apple", "banana", "cherry"];
const fruitString = fruits.toString();
console.log(fruitString); // Output: "apple,banana,cherry"
console.log(typeof fruitString); // Output: "string"
For nested arrays, it also convert the inner arrays to strings.
const nestedArray = [1, 2, [3, 4]];
const stringified = nestedArray.toString();
console.log(stringified); // Output: "1,2,3,4"
entries()
Returns a new Array Iterator object that contains key/value pairs for each index in the array. This iterator is a convenient way to loop through an array while getting both the index (key) and the element (value) for each item.
const fruits = ["apple", "banana", "cherry"];
// The entry is an array like [index, element]
for (const entry of fruits.entries()) {
console.log(entry);
}
// Output:
// [0, 'apple']
// [1, 'banana']
// [2, 'cherry']
// You can also destructure the entry directly
for (const [index, fruit] of fruits.entries()) {
console.log(`The fruit at index ${index} is ${fruit}.`);
}
// Output:
// The fruit at index 0 is apple.
// The fruit at index 1 is banana.
// The fruit at index 2 is cherry.
9. Advanced Tips & Best Practices
Chaining Methods
One of the greatest strengths of array methods is that can chain together to create a clean, readable data processing pipeline.
const users = [
{ name: "Alice", active: false },
{ name: "Bob", active: true },
{ name: "Charlie", active: true },
];
const activeUserNames = users
.filter((user) => user.active) // Returns [{name: 'Bob', active: true}, {name: 'Charlie', active: true}]
.map((user) => user.name); // Returns ['Bob', 'Charlie']
console.log(activeUserNames); // Output: ['Bob', 'Charlie']
Immutability
In modern JavaScript development, especially with frameworks like React, the concept of immutability is crucial. This means you should avoid changing the original array and instead create a new one with your desired changes. This prevents unexpected side effects and makes your code more predictable.
const originalArray = [1, 2, 3];
// Bad Practice (Mutates original)
const badReverse = originalArray.reverse();
console.log(originalArray); // Output: [3, 2, 1] - Oops, changed the original!
// Good Practice (Creates a new array)
const goodReverse = [...originalArray].reverse();
console.log(originalArray); // Output: [1, 2, 3] - Original remains unchanged
console.log(goodReverse); // Output: [3, 2, 1]
Use reduce()
for Complex Transformations
While map()
and filter()
are great for their specific tasks, reduce()
is the most versatile method. It can do almost anything the others can, and more. Use it when you need to transform an array into a single value or a different data structure, like an object.
const students = [
{ name: "Alice", grade: "A" },
{ name: "Bob", grade: "B" },
{ name: "Charlie", grade: "A" },
];
const gradesGrouped = students.reduce((accumulator, student) => {
const grade = student.grade;
if (!accumulator[grade]) {
accumulator[grade] = [];
}
accumulator[grade].push(student.name);
return accumulator;
}, {});
console.log(gradesGrouped);
/* Output:
{
A: ["Alice", "Charlie"],
B: ["Bob"]
}
*/
Choosing the Right Method
Knowing when to use each method is key to writing good code.
- Use
forEach()
when you just need to loop and perform an action (a side effect). - Use
map()
when you need to transform every item and get a new array of the same length. - Use
filter()
when you need to select a subset of elements that meet a condition. - Use
reduce()
when you need to compute a single value or transform an array into a new, different data structure. - Use
find()
andsome()
for simple existence checks, as they stop iterating early and are more efficient thanfilter()
for this purpose.
TL;DR
- Arrays in JavaScript have 40+ methods across creation, searching, iteration, mutation, and conversion.
- Modern methods (
with
,toSorted
,toSpliced
) make arrays immutable-friendly. - Mastering
reduce
,map
, andfilter
lets you write expressive, declarative code. - Use chaining methods to create a clean, readable data processing pipeline.
- Avoid mutating arrays directly, use
map
andreduce
instead.
10. References
Here are some useful references to dive deeper into JavaScript array methods:
- MDN Web Docs: Array – Complete official documentation with examples.
- JavaScript.info: Arrays – Beginner to advanced guide on arrays.
- W3Schools: JavaScript Arrays – Quick reference with interactive examples.
- ECMAScript Specification – Array Objects – Technical standard (for advanced readers).
- 30 Seconds of Code – Array Snippets – Handy array method snippets and tricks.
- You Don’t Know JS (Book) – In-depth explanations of JavaScript core concepts.
Keep practicing with real-world scenarios (data filtering, transformations, aggregations) to build muscle memory. Arrays are everywhere in JavaScript — the better you know them, the stronger your foundation as a developer.
Top comments (0)