Arrays
Table of Contents
Arrays are one of the most-used data structures in JavaScript. They’re ordered lists of values, and they come with a rich set of built-in methods for searching, transforming, and iterating over data. If you’ve worked through Functions, you’ve already seen map, filter, and reduce in passing — this tutorial covers arrays from the ground up.
Creating Arrays
// Array literal (most common)
const fruits = ["apple", "banana", "cherry"];
// Empty array
const empty = [];
// Arrays can hold mixed types (though you usually wouldn't)
const mixed = [1, "hello", true, null, { name: "Alice" }];
// Array.from — create an array from an iterable
const letters = Array.from("hello"); // ["h", "e", "l", "l", "o"]
// Array.of — create an array from arguments
const nums = Array.of(1, 2, 3); // [1, 2, 3]
Accessing and Modifying Elements
Arrays are zero-indexed — the first element is at index 0:
const colors = ["red", "green", "blue"];
console.log(colors[0]); // "red"
console.log(colors[2]); // "blue"
console.log(colors.length); // 3
console.log(colors[colors.length - 1]); // "blue" (last element)
// Modify an element
colors[1] = "yellow";
console.log(colors); // ["red", "yellow", "blue"]
at() — Negative Indexing
The at() method supports negative indices, which count from the end:
const items = ["a", "b", "c", "d"];
console.log(items.at(0)); // "a"
console.log(items.at(-1)); // "d" (last)
console.log(items.at(-2)); // "c" (second to last)
Adding and Removing Elements
const stack = [1, 2, 3];
// End of array
stack.push(4); // [1, 2, 3, 4] — add to end
stack.pop(); // [1, 2, 3] — remove from end (returns 4)
// Beginning of array
stack.unshift(0); // [0, 1, 2, 3] — add to beginning
stack.shift(); // [1, 2, 3] — remove from beginning (returns 0)
push/pop are fast (O(1)). unshift/shift are slow on large arrays (O(n)) because every element has to be re-indexed. If you need frequent additions at both ends, consider a different data structure.
splice — Insert, Remove, or Replace Anywhere
splice is the Swiss army knife of array mutation. It modifies the array in place and returns the removed elements:
const arr = ["a", "b", "c", "d", "e"];
// Remove 2 elements starting at index 1
const removed = arr.splice(1, 2);
console.log(arr); // ["a", "d", "e"]
console.log(removed); // ["b", "c"]
// Insert at index 1 (remove 0 elements)
arr.splice(1, 0, "x", "y");
console.log(arr); // ["a", "x", "y", "d", "e"]
// Replace 1 element at index 2
arr.splice(2, 1, "z");
console.log(arr); // ["a", "x", "z", "d", "e"]
Iterating Over Arrays
for…of
The cleanest way to loop through values:
const fruits = ["apple", "banana", "cherry"];
for (const fruit of fruits) {
console.log(fruit);
}
forEach
Calls a function for each element. Useful but can’t break out early:
fruits.forEach((fruit, index) => {
console.log(`${index}: ${fruit}`);
});
Classic for Loop
Use when you need the index or need to skip/break:
for (let i = 0; i < fruits.length; i++) {
if (fruits[i] === "banana") break;
console.log(fruits[i]);
}
Transforming Arrays
These methods return a new array without modifying the original. They’re the foundation of functional-style JavaScript.
map — Transform Each Element
const numbers = [1, 2, 3, 4, 5];
const doubled = numbers.map(n => n * 2);
console.log(doubled); // [2, 4, 6, 8, 10]
const users = [
{ name: "Alice", age: 25 },
{ name: "Bob", age: 30 },
];
const names = users.map(user => user.name);
console.log(names); // ["Alice", "Bob"]
filter — Keep Elements That Match
const numbers = [1, 2, 3, 4, 5, 6];
const evens = numbers.filter(n => n % 2 === 0);
console.log(evens); // [2, 4, 6]
const adults = users.filter(user => user.age >= 18);
reduce — Combine Into a Single Value
reduce is the most powerful array method. It takes an accumulator and processes each element:
const numbers = [1, 2, 3, 4, 5];
const sum = numbers.reduce((total, n) => total + n, 0);
console.log(sum); // 15
// Count occurrences
const words = ["yes", "no", "yes", "yes", "no"];
const counts = words.reduce((acc, word) => {
acc[word] = (acc[word] || 0) + 1;
return acc;
}, {});
console.log(counts); // { yes: 3, no: 2 }
Chaining Methods
These methods return arrays, so you can chain them:
const products = [
{ name: "Laptop", price: 999, inStock: true },
{ name: "Phone", price: 699, inStock: false },
{ name: "Tablet", price: 449, inStock: true },
{ name: "Watch", price: 299, inStock: true },
];
const affordableInStock = products
.filter(p => p.inStock)
.filter(p => p.price < 500)
.map(p => p.name);
console.log(affordableInStock); // ["Tablet", "Watch"]
Searching
const numbers = [10, 20, 30, 40, 50];
// find — first element matching a condition
const found = numbers.find(n => n > 25);
console.log(found); // 30
// findIndex — index of first match
const idx = numbers.findIndex(n => n > 25);
console.log(idx); // 2
// includes — does the array contain a value?
console.log(numbers.includes(30)); // true
console.log(numbers.includes(99)); // false
// indexOf — index of a specific value (-1 if not found)
console.log(numbers.indexOf(30)); // 2
// some — does at least one element match?
console.log(numbers.some(n => n > 40)); // true
// every — do all elements match?
console.log(numbers.every(n => n > 5)); // true
Sorting
sort modifies the array in place. By default, it sorts elements as strings, which produces surprising results with numbers:
const nums = [10, 1, 21, 2];
nums.sort();
console.log(nums); // [1, 10, 2, 21] — string sort!
// Numeric sort — pass a compare function
nums.sort((a, b) => a - b);
console.log(nums); // [1, 2, 10, 21]
// Descending
nums.sort((a, b) => b - a);
console.log(nums); // [21, 10, 2, 1]
Sort objects by a property:
const users = [
{ name: "Charlie", age: 35 },
{ name: "Alice", age: 25 },
{ name: "Bob", age: 30 },
];
users.sort((a, b) => a.age - b.age);
console.log(users.map(u => u.name)); // ["Alice", "Bob", "Charlie"]
sort() mutates the original array. If you need to keep the original, copy first: [...arr].sort().
Other Useful Methods
const a = [1, 2, 3];
const b = [4, 5, 6];
// concat — merge arrays
console.log(a.concat(b)); // [1, 2, 3, 4, 5, 6]
// spread (modern alternative)
console.log([...a, ...b]); // [1, 2, 3, 4, 5, 6]
// slice — extract a portion (does NOT mutate)
const arr = [10, 20, 30, 40, 50];
console.log(arr.slice(1, 3)); // [20, 30]
console.log(arr.slice(-2)); // [40, 50]
// flat — flatten 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]
// join — convert to string
console.log(["a", "b", "c"].join("-")); // "a-b-c"
// reverse — reverses in place
const letters = ["a", "b", "c"];
letters.reverse();
console.log(letters); // ["c", "b", "a"]
Destructuring Arrays
Destructuring lets you unpack array values into variables. We covered this in Variables and Data Types, but it’s worth revisiting in the context of arrays:
const [first, second, ...rest] = [10, 20, 30, 40, 50];
console.log(first); // 10
console.log(second); // 20
console.log(rest); // [30, 40, 50]
// Swap variables
let x = 1, y = 2;
[x, y] = [y, x];
console.log(x, y); // 2, 1
Putting It Together: Data Processing
Here’s a realistic example — processing a list of orders to generate a summary:
const orders = [
{ id: 1, customer: "Alice", total: 59.99, status: "shipped" },
{ id: 2, customer: "Bob", total: 124.50, status: "pending" },
{ id: 3, customer: "Alice", total: 34.00, status: "shipped" },
{ id: 4, customer: "Charlie", total: 89.99, status: "shipped" },
{ id: 5, customer: "Bob", total: 210.00, status: "pending" },
];
// Total revenue from shipped orders
const shippedRevenue = orders
.filter(o => o.status === "shipped")
.reduce((sum, o) => sum + o.total, 0);
console.log(`Shipped revenue: $${shippedRevenue.toFixed(2)}`);
// "Shipped revenue: $183.98"
// Spending per customer
const spending = orders.reduce((acc, o) => {
acc[o.customer] = (acc[o.customer] || 0) + o.total;
return acc;
}, {});
console.log(spending);
// { Alice: 93.99, Bob: 334.5, Charlie: 89.99 }
// Customers with pending orders
const pendingCustomers = [...new Set(
orders.filter(o => o.status === "pending").map(o => o.customer)
)];
console.log(pendingCustomers); // ["Bob"]
What’s Next
Arrays pair naturally with objects — most real-world data is arrays of objects. From there, you’ll be ready to tackle DOM Manipulation to use these skills in the browser.