DEV Community

Cover image for JavaScript Array Methods: A Guide with Examples
Mohammed Taysser
Mohammed Taysser

Posted on

JavaScript Array Methods: A Guide with Examples

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

  1. Creating Arrays
  2. Adding and Removing Elements
  3. Searching and Finding
  4. Iteration Methods
  5. Sorting and Reversing
  6. Joining and Flattening
  7. Copying and Filling
  8. Conversion
  9. Advanced Tips & Best Practices
  10. TL;DR
  11. 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]
Enter fullscreen mode Exit fullscreen mode

Note: of(5) method is similar to new Array(5). But the main difference is new Array(5) creates an empty array with length 5, while of(5) creates array with 5 length and all elements initialized to undefined.

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]
Enter fullscreen mode Exit fullscreen mode

Note: .from method is similar to map(). In more details, .from(obj, mapFn) has the same result as .from(obj).map(mapFn), except that it does not create an intermediate array, and mapFn 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"]
Enter fullscreen mode Exit fullscreen mode

pop()

Remove last element and returns that element.

const fruits = ["apple", "banana"];
const lastElement = fruits.pop();
console.log(lastElement); // "banana"
console.log(fruits); // ["apple"]
Enter fullscreen mode Exit fullscreen mode

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]
Enter fullscreen mode Exit fullscreen mode

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]
Enter fullscreen mode Exit fullscreen mode

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']
Enter fullscreen mode Exit fullscreen mode

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']
Enter fullscreen mode Exit fullscreen mode

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']
Enter fullscreen mode Exit fullscreen mode

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]
Enter fullscreen mode Exit fullscreen mode

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']
Enter fullscreen mode Exit fullscreen mode

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']
Enter fullscreen mode Exit fullscreen mode

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']
Enter fullscreen mode Exit fullscreen mode

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)
Enter fullscreen mode Exit fullscreen mode
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
Enter fullscreen mode Exit fullscreen mode

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)
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode
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)
Enter fullscreen mode Exit fullscreen mode

A key advantage of includes() is its ability to find NaN, which indexOf() cannot.

const numbersWithNaN = [1, 2, NaN];

console.log(numbersWithNaN.includes(NaN)); // Output: true

console.log(numbersWithNaN.indexOf(NaN)); // Output: -1
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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.
Enter fullscreen mode Exit fullscreen mode

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']
Enter fullscreen mode Exit fullscreen mode

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' }
]
*/
Enter fullscreen mode Exit fullscreen mode

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 the initialValue 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 }
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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 a string.

const fruits = ["banana", "apple", "cherry"];
fruits.sort();

console.log(fruits); // Output: ['apple', 'banana', 'cherry']
Enter fullscreen mode Exit fullscreen mode

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]
Enter fullscreen mode Exit fullscreen mode

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]
Enter fullscreen mode Exit fullscreen mode

The a - b logic works because:

  • If a is less than b, a - b is negative, so a comes first.
  • If a is greater than b, a - b is positive, so b 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 }
]
*/
Enter fullscreen mode Exit fullscreen mode

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]
Enter fullscreen mode Exit fullscreen mode

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"
Enter fullscreen mode Exit fullscreen mode

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]
Enter fullscreen mode Exit fullscreen mode

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]
Enter fullscreen mode Exit fullscreen mode

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']
Enter fullscreen mode Exit fullscreen mode

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]
Enter fullscreen mode Exit fullscreen mode

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']
Enter fullscreen mode Exit fullscreen mode

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']
Enter fullscreen mode Exit fullscreen mode

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']
Enter fullscreen mode Exit fullscreen mode

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"
Enter fullscreen mode Exit fullscreen mode

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"
Enter fullscreen mode Exit fullscreen mode

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.
Enter fullscreen mode Exit fullscreen mode

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']
Enter fullscreen mode Exit fullscreen mode

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]
Enter fullscreen mode Exit fullscreen mode

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"]
}
*/
Enter fullscreen mode Exit fullscreen mode

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() and some() for simple existence checks, as they stop iterating early and are more efficient than filter() 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, and filter lets you write expressive, declarative code.
  • Use chaining methods to create a clean, readable data processing pipeline.
  • Avoid mutating arrays directly, use map and reduce instead.

10. References

Here are some useful references to dive deeper into JavaScript array methods:

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)