JavaScript BasicsFeatured
JavaScript Array Methods: The Ultimate Guide
Complete guide to JavaScript array methods with examples. Master array manipulation, transformation, iteration, and modern array handling techniques.
By JavaScript Document Team•
arraysmethodsbasicsreferencemanipulation
Arrays are fundamental data structures in JavaScript, providing powerful methods for data manipulation and transformation. This comprehensive guide covers all JavaScript array methods with practical examples to help you master array operations.
Array Creation
Array Literals and Constructor
// Array literal (preferred)
const arr1 = [1, 2, 3, 4, 5];
const arr2 = ['apple', 'banana', 'orange'];
const arr3 = [1, 'two', true, null, undefined];
// Array constructor
const arr4 = new Array(5); // Creates array with 5 empty slots
const arr5 = new Array(1, 2, 3); // Creates [1, 2, 3]
// Array.of() - creates array from arguments
const arr6 = Array.of(5); // [5] (not empty array)
const arr7 = Array.of(1, 2, 3); // [1, 2, 3]
// Array.from() - creates array from iterable
const arr8 = Array.from('hello'); // ['h', 'e', 'l', 'l', 'o']
const arr9 = Array.from([1, 2, 3], (x) => x * 2); // [2, 4, 6]
// Creating array with specific length and values
const zeros = Array(5).fill(0); // [0, 0, 0, 0, 0]
const sequence = Array.from({ length: 5 }, (_, i) => i); // [0, 1, 2, 3, 4]
Array Properties
length
const fruits = ['apple', 'banana', 'orange'];
console.log(fruits.length); // 3
// Modifying length
fruits.length = 2;
console.log(fruits); // ['apple', 'banana']
fruits.length = 5;
console.log(fruits); // ['apple', 'banana', empty × 3]
// Truncating array
const numbers = [1, 2, 3, 4, 5];
numbers.length = 0; // Empties the array
console.log(numbers); // []
Adding and Removing Elements
push() and pop()
const stack = [];
// push() - adds elements to end, returns new length
console.log(stack.push(1)); // 1
console.log(stack.push(2, 3)); // 3
console.log(stack); // [1, 2, 3]
// pop() - removes and returns last element
console.log(stack.pop()); // 3
console.log(stack); // [1, 2]
console.log(stack.pop()); // 2
console.log(stack.pop()); // 1
console.log(stack.pop()); // undefined (empty array)
unshift() and shift()
const queue = [];
// unshift() - adds elements to beginning, returns new length
console.log(queue.unshift(1)); // 1
console.log(queue.unshift(2, 3)); // 3
console.log(queue); // [2, 3, 1]
// shift() - removes and returns first element
console.log(queue.shift()); // 2
console.log(queue); // [3, 1]
console.log(queue.shift()); // 3
console.log(queue.shift()); // 1
console.log(queue.shift()); // undefined
splice()
const arr = ['a', 'b', 'c', 'd', 'e'];
// Remove elements: splice(start, deleteCount)
const removed = arr.splice(2, 2);
console.log(arr); // ['a', 'b', 'e']
console.log(removed); // ['c', 'd']
// Insert elements: splice(start, 0, ...items)
arr.splice(1, 0, 'x', 'y');
console.log(arr); // ['a', 'x', 'y', 'b', 'e']
// Replace elements: splice(start, deleteCount, ...items)
arr.splice(2, 2, 'z');
console.log(arr); // ['a', 'x', 'z', 'e']
// Negative index
arr.splice(-1, 1, 'END');
console.log(arr); // ['a', 'x', 'z', 'END']
Array Transformation Methods
map()
const numbers = [1, 2, 3, 4, 5];
// Basic transformation
const doubled = numbers.map((n) => n * 2);
console.log(doubled); // [2, 4, 6, 8, 10]
// With index and array parameters
const indexed = numbers.map((value, index, array) => {
return `${index}: ${value} of ${array.length}`;
});
console.log(indexed);
// ['0: 1 of 5', '1: 2 of 5', '2: 3 of 5', '3: 4 of 5', '4: 5 of 5']
// Object transformation
const users = [
{ name: 'Alice', age: 25 },
{ name: 'Bob', age: 30 },
{ name: 'Charlie', age: 35 },
];
const names = users.map((user) => user.name);
console.log(names); // ['Alice', 'Bob', 'Charlie']
const enhanced = users.map((user) => ({
...user,
isAdult: user.age >= 18,
category: user.age < 30 ? 'young' : 'adult',
}));
filter()
const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
// Basic filtering
const evens = numbers.filter((n) => n % 2 === 0);
console.log(evens); // [2, 4, 6, 8, 10]
// Complex filtering
const products = [
{ name: 'Laptop', price: 999, inStock: true },
{ name: 'Mouse', price: 29, inStock: false },
{ name: 'Keyboard', price: 79, inStock: true },
{ name: 'Monitor', price: 299, inStock: true },
];
const availableUnder100 = products.filter(
(product) => product.inStock && product.price < 100
);
console.log(availableUnder100);
// [{ name: 'Keyboard', price: 79, inStock: true }]
// Chaining with map
const affordableNames = products
.filter((p) => p.price < 300)
.map((p) => p.name);
console.log(affordableNames); // ['Mouse', 'Keyboard', 'Monitor']
reduce()
const numbers = [1, 2, 3, 4, 5];
// Sum
const sum = numbers.reduce((acc, num) => acc + num, 0);
console.log(sum); // 15
// Product
const product = numbers.reduce((acc, num) => acc * num, 1);
console.log(product); // 120
// Find max
const max = numbers.reduce((max, num) => (num > max ? num : max));
console.log(max); // 5
// Group by property
const people = [
{ name: 'Alice', age: 25, city: 'NYC' },
{ name: 'Bob', age: 30, city: 'LA' },
{ name: 'Charlie', age: 35, city: 'NYC' },
{ name: 'David', age: 40, city: 'LA' },
];
const byCity = people.reduce((groups, person) => {
const city = person.city;
if (!groups[city]) groups[city] = [];
groups[city].push(person);
return groups;
}, {});
console.log(byCity);
// { NYC: [{Alice}, {Charlie}], LA: [{Bob}, {David}] }
// Flatten array
const nested = [
[1, 2],
[3, 4],
[5, 6],
];
const flat = nested.reduce((acc, arr) => acc.concat(arr), []);
console.log(flat); // [1, 2, 3, 4, 5, 6]
reduceRight()
const numbers = [1, 2, 3, 4, 5];
// Right-to-left reduction
const result = numbers.reduceRight((acc, num) => {
console.log(`${acc} - ${num}`);
return acc - num;
});
// 5 - 4
// 1 - 3
// -2 - 2
// -4 - 1
console.log(result); // -5
// Building string from right to left
const words = ['World', 'Hello'];
const sentence = words.reduceRight((acc, word) => acc + ' ' + word);
console.log(sentence); // 'Hello World'
Searching and Finding
find() and findIndex()
const users = [
{ id: 1, name: 'Alice', age: 25 },
{ id: 2, name: 'Bob', age: 30 },
{ id: 3, name: 'Charlie', age: 35 },
];
// find() - returns first matching element
const user = users.find((u) => u.age > 28);
console.log(user); // { id: 2, name: 'Bob', age: 30 }
const noUser = users.find((u) => u.age > 40);
console.log(noUser); // undefined
// findIndex() - returns index of first match
const index = users.findIndex((u) => u.name === 'Charlie');
console.log(index); // 2
const noIndex = users.findIndex((u) => u.name === 'David');
console.log(noIndex); // -1
findLast() and findLastIndex()
const numbers = [1, 2, 3, 4, 5, 4, 3, 2, 1];
// findLast() - returns last matching element (ES2023)
const lastEven = numbers.findLast((n) => n % 2 === 0);
console.log(lastEven); // 2
// findLastIndex() - returns index of last match (ES2023)
const lastIndexOf4 = numbers.findLastIndex((n) => n === 4);
console.log(lastIndexOf4); // 5
indexOf() and lastIndexOf()
const arr = ['a', 'b', 'c', 'b', 'a'];
// indexOf() - first occurrence
console.log(arr.indexOf('b')); // 1
console.log(arr.indexOf('d')); // -1
console.log(arr.indexOf('b', 2)); // 3 (search from index 2)
// lastIndexOf() - last occurrence
console.log(arr.lastIndexOf('b')); // 3
console.log(arr.lastIndexOf('b', 2)); // 1 (search backwards from index 2)
// Checking existence
const hasB = arr.indexOf('b') !== -1;
console.log(hasB); // true
includes()
const arr = [1, 2, 3, NaN];
console.log(arr.includes(2)); // true
console.log(arr.includes(4)); // false
console.log(arr.includes(NaN)); // true (works with NaN!)
// With fromIndex
console.log(arr.includes(1, 1)); // false (search from index 1)
console.log(arr.includes(3, -2)); // true (search from index 2)
// vs indexOf
console.log(arr.indexOf(NaN)); // -1 (doesn't work with NaN)
console.log(arr.includes(NaN)); // true
Testing Methods
every() and some()
const numbers = [2, 4, 6, 8, 10];
// every() - tests if all elements pass
const allEven = numbers.every((n) => n % 2 === 0);
console.log(allEven); // true
const allGreaterThan5 = numbers.every((n) => n > 5);
console.log(allGreaterThan5); // false
// some() - tests if at least one element passes
const someGreaterThan5 = numbers.some((n) => n > 5);
console.log(someGreaterThan5); // true
const someOdd = numbers.some((n) => n % 2 !== 0);
console.log(someOdd); // false
// Empty array behavior
console.log([].every((x) => false)); // true (vacuous truth)
console.log([].some((x) => true)); // false
Iteration Methods
forEach()
const fruits = ['apple', 'banana', 'orange'];
// Basic iteration
fruits.forEach((fruit) => console.log(fruit));
// With index and array
fruits.forEach((fruit, index, array) => {
console.log(`${index}: ${fruit} (${array.length} total)`);
});
// Cannot break out of forEach
let count = 0;
fruits.forEach((fruit) => {
if (count >= 2) return; // This doesn't break the loop
console.log(fruit);
count++;
});
// Still logs all fruits
// Side effects
const numbers = [1, 2, 3];
const doubled = [];
numbers.forEach((n) => doubled.push(n * 2));
console.log(doubled); // [2, 4, 6]
for...of
const arr = ['a', 'b', 'c'];
// Basic iteration
for (const value of arr) {
console.log(value); // a, b, c
}
// With index using entries()
for (const [index, value] of arr.entries()) {
console.log(`${index}: ${value}`);
}
// Can break/continue
for (const value of arr) {
if (value === 'b') break;
console.log(value); // Only logs 'a'
}
Array Flattening
flat() and flatMap()
// flat() - flattens nested arrays
const nested = [1, [2, 3], [4, [5, 6]]];
console.log(nested.flat()); // [1, 2, 3, 4, [5, 6]]
console.log(nested.flat(2)); // [1, 2, 3, 4, 5, 6]
console.log(nested.flat(Infinity)); // [1, 2, 3, 4, 5, 6]
// Removing empty slots
const sparse = [1, , 3, , 5];
console.log(sparse.flat()); // [1, 3, 5]
// flatMap() - map + flat(1)
const sentences = ['Hello World', 'How are you'];
const words = sentences.flatMap((sentence) => sentence.split(' '));
console.log(words); // ['Hello', 'World', 'How', 'are', 'you']
// Filtering with flatMap
const numbers = [1, 2, 3, 4, 5];
const evenDoubled = numbers.flatMap((n) => (n % 2 === 0 ? [n * 2] : []));
console.log(evenDoubled); // [4, 8]
Sorting and Reversing
sort()
// Default sort (alphabetical)
const fruits = ['banana', 'apple', 'cherry'];
fruits.sort();
console.log(fruits); // ['apple', 'banana', 'cherry']
// Number sorting (incorrect without compare function)
const numbers = [10, 5, 40, 25, 1000, 1];
numbers.sort();
console.log(numbers); // [1, 10, 1000, 25, 40, 5] (alphabetical!)
// Correct number sorting
numbers.sort((a, b) => a - b);
console.log(numbers); // [1, 5, 10, 25, 40, 1000]
// Descending order
numbers.sort((a, b) => b - a);
console.log(numbers); // [1000, 40, 25, 10, 5, 1]
// Object sorting
const users = [
{ name: 'John', age: 30 },
{ name: 'Alice', age: 25 },
{ name: 'Bob', age: 35 },
];
users.sort((a, b) => a.age - b.age);
console.log(users); // Sorted by age
// Stable sort (ES2019+)
const items = [
{ name: 'A', value: 1 },
{ name: 'B', value: 1 },
{ name: 'C', value: 2 },
];
items.sort((a, b) => a.value - b.value);
// Order of A and B is preserved
reverse()
const arr = [1, 2, 3, 4, 5];
// Mutates original array
arr.reverse();
console.log(arr); // [5, 4, 3, 2, 1]
// To avoid mutation
const original = [1, 2, 3];
const reversed = [...original].reverse();
console.log(original); // [1, 2, 3]
console.log(reversed); // [3, 2, 1]
toSorted() and toReversed() (ES2023)
const numbers = [3, 1, 4, 1, 5];
// toSorted() - returns new sorted array
const sorted = numbers.toSorted();
console.log(numbers); // [3, 1, 4, 1, 5] (unchanged)
console.log(sorted); // [1, 1, 3, 4, 5]
// toReversed() - returns new reversed array
const reversed = numbers.toReversed();
console.log(numbers); // [3, 1, 4, 1, 5] (unchanged)
console.log(reversed); // [5, 1, 4, 1, 3]
Copying and Combining Arrays
concat()
const arr1 = [1, 2, 3];
const arr2 = [4, 5, 6];
const arr3 = [7, 8, 9];
// Combining arrays
const combined = arr1.concat(arr2, arr3);
console.log(combined); // [1, 2, 3, 4, 5, 6, 7, 8, 9]
// With individual values
const withValues = arr1.concat(4, 5, [6, 7]);
console.log(withValues); // [1, 2, 3, 4, 5, 6, 7]
// Shallow copy
const nested = [[1]];
const concatenated = nested.concat([[2]]);
nested[0].push(2);
console.log(concatenated); // [[1, 2], [2]] (affected by mutation)
slice()
const arr = ['a', 'b', 'c', 'd', 'e'];
// Extract portion
console.log(arr.slice(1, 4)); // ['b', 'c', 'd']
console.log(arr.slice(2)); // ['c', 'd', 'e']
console.log(arr.slice(-2)); // ['d', 'e']
console.log(arr.slice(1, -1)); // ['b', 'c', 'd']
// Copy entire array
const copy = arr.slice();
console.log(copy); // ['a', 'b', 'c', 'd', 'e']
// Shallow copy warning
const objects = [{ a: 1 }, { b: 2 }];
const sliced = objects.slice();
objects[0].a = 999;
console.log(sliced[0]); // { a: 999 } (affected!)
Spread Operator
const arr1 = [1, 2, 3];
const arr2 = [4, 5, 6];
// Combining arrays
const combined = [...arr1, ...arr2];
console.log(combined); // [1, 2, 3, 4, 5, 6]
// Copying array
const copy = [...arr1];
console.log(copy); // [1, 2, 3]
// With additional elements
const extended = [0, ...arr1, 3.5, ...arr2, 7];
console.log(extended); // [0, 1, 2, 3, 3.5, 4, 5, 6, 7]
Converting Arrays
join()
const arr = ['Hello', 'World'];
console.log(arr.join()); // 'Hello,World' (default comma)
console.log(arr.join(' ')); // 'Hello World'
console.log(arr.join('-')); // 'Hello-World'
console.log(arr.join('')); // 'HelloWorld'
// With numbers
const numbers = [1, 2, 3];
console.log(numbers.join(' + ')); // '1 + 2 + 3'
// Empty elements
const sparse = [1, , 3];
console.log(sparse.join('-')); // '1--3'
toString() and toLocaleString()
const arr = [1, 2, 3];
console.log(arr.toString()); // '1,2,3'
const mixed = [1, 'two', true, null, undefined];
console.log(mixed.toString()); // '1,two,true,,'
// toLocaleString()
const numbers = [1234.5, 6789.1];
console.log(numbers.toLocaleString('en-US')); // '1,234.5,6,789.1'
console.log(numbers.toLocaleString('de-DE')); // '1.234,5.6.789,1'
const dates = [new Date()];
console.log(dates.toLocaleString()); // Locale-specific date format
Array-like Methods
keys(), values(), and entries()
const arr = ['a', 'b', 'c'];
// keys() - returns iterator of indices
for (const key of arr.keys()) {
console.log(key); // 0, 1, 2
}
// values() - returns iterator of values
for (const value of arr.values()) {
console.log(value); // 'a', 'b', 'c'
}
// entries() - returns iterator of [index, value] pairs
for (const [index, value] of arr.entries()) {
console.log(`${index}: ${value}`);
}
// 0: a
// 1: b
// 2: c
// Convert to array
console.log([...arr.keys()]); // [0, 1, 2]
console.log([...arr.values()]); // ['a', 'b', 'c']
console.log([...arr.entries()]); // [[0, 'a'], [1, 'b'], [2, 'c']]
Modern Array Methods
at()
const arr = ['a', 'b', 'c', 'd'];
// Positive indices
console.log(arr.at(0)); // 'a'
console.log(arr.at(2)); // 'c'
// Negative indices
console.log(arr.at(-1)); // 'd'
console.log(arr.at(-2)); // 'c'
// Out of bounds
console.log(arr.at(10)); // undefined
console.log(arr.at(-10)); // undefined
// vs bracket notation
console.log(arr[-1]); // undefined (doesn't work)
console.log(arr.at(-1)); // 'd' (works!)
with() (ES2023)
const arr = [1, 2, 3, 4, 5];
// with() - returns new array with element replaced
const updated = arr.with(2, 99);
console.log(arr); // [1, 2, 3, 4, 5] (unchanged)
console.log(updated); // [1, 2, 99, 4, 5]
// Negative indices
const lastUpdated = arr.with(-1, 100);
console.log(lastUpdated); // [1, 2, 3, 4, 100]
toSpliced() (ES2023)
const arr = ['a', 'b', 'c', 'd', 'e'];
// toSpliced() - returns new array with splice applied
const removed = arr.toSpliced(1, 2);
console.log(arr); // ['a', 'b', 'c', 'd', 'e'] (unchanged)
console.log(removed); // ['a', 'd', 'e']
const inserted = arr.toSpliced(2, 0, 'X', 'Y');
console.log(inserted); // ['a', 'b', 'X', 'Y', 'c', 'd', 'e']
Practical Examples
Remove Duplicates
const numbers = [1, 2, 2, 3, 4, 4, 5];
// Using Set
const unique1 = [...new Set(numbers)];
console.log(unique1); // [1, 2, 3, 4, 5]
// Using filter with indexOf
const unique2 = numbers.filter(
(item, index) => numbers.indexOf(item) === index
);
console.log(unique2); // [1, 2, 3, 4, 5]
// Using reduce
const unique3 = numbers.reduce(
(acc, num) => (acc.includes(num) ? acc : [...acc, num]),
[]
);
console.log(unique3); // [1, 2, 3, 4, 5]
Array Intersection and Union
const arr1 = [1, 2, 3, 4, 5];
const arr2 = [4, 5, 6, 7, 8];
// Intersection
const intersection = arr1.filter((x) => arr2.includes(x));
console.log(intersection); // [4, 5]
// Union
const union = [...new Set([...arr1, ...arr2])];
console.log(union); // [1, 2, 3, 4, 5, 6, 7, 8]
// Difference (arr1 - arr2)
const difference = arr1.filter((x) => !arr2.includes(x));
console.log(difference); // [1, 2, 3]
Group By (Manual Implementation)
const people = [
{ name: 'Alice', age: 25, city: 'NYC' },
{ name: 'Bob', age: 30, city: 'LA' },
{ name: 'Charlie', age: 25, city: 'NYC' },
{ name: 'David', age: 30, city: 'Chicago' },
];
// Group by age
const groupByAge = people.reduce((groups, person) => {
const age = person.age;
groups[age] = groups[age] || [];
groups[age].push(person);
return groups;
}, {});
console.log(groupByAge);
// { 25: [Alice, Charlie], 30: [Bob, David] }
// Generic groupBy function
function groupBy(array, key) {
return array.reduce((groups, item) => {
const group = item[key];
groups[group] = groups[group] || [];
groups[group].push(item);
return groups;
}, {});
}
console.log(groupBy(people, 'city'));
Performance Considerations
- Mutation vs Immutability: Methods like
sort()
andreverse()
mutate the original array - Method Chaining: Can be elegant but creates intermediate arrays
- Large Arrays: Consider using
for
loops for better performance - Sparse Arrays: Be aware of how different methods handle empty slots
- Memory Usage: Methods like
map()
andfilter()
create new arrays
Conclusion
JavaScript arrays provide a rich set of methods for every data manipulation need. Understanding when and how to use each method is crucial for writing efficient and maintainable code. Practice combining these methods to solve complex problems elegantly.