Arrays in JavaScript
Arrays are ordered collections of values. They're versatile data structures for storing and manipulating lists of data efficiently.
📝 Creating Arrays
// Array literal (preferred)
let fruits = ['apple', 'banana', 'orange'];
let numbers = [1, 2, 3, 4, 5];
let mixed = [1, 'hello', true, null, { name: 'John' }];
// Array constructor
let arr1 = new Array(3); // [empty × 3]
let arr2 = new Array(1, 2, 3); // [1, 2, 3]
// Array.of() - creates array from arguments
let arr3 = Array.of(5); // [5] (not [empty × 5])
let arr4 = Array.of(1, 2, 3); // [1, 2, 3]
// Array.from() - create from array-like or iterable
let str = 'hello';
let chars = Array.from(str); // ['h', 'e', 'l', 'l', 'o']
let range = Array.from({ length: 5 }, (_, i) => i);
console.log(range); // [0, 1, 2, 3, 4]
// Spread operator
let original = [1, 2, 3];
let copy = [...original]; // [1, 2, 3]
let combined = [...original, 4, 5]; // [1, 2, 3, 4, 5]
🔍 Accessing Elements
let fruits = ['apple', 'banana', 'orange', 'grape', 'mango'];
// By index (zero-based)
console.log(fruits[0]); // 'apple'
console.log(fruits[2]); // 'orange'
console.log(fruits[10]); // undefined
// Negative indexing with at() (ES2022)
console.log(fruits.at(0)); // 'apple'
console.log(fruits.at(-1)); // 'mango' (last item)
console.log(fruits.at(-2)); // 'grape'
// First and last
let first = fruits[0];
let last = fruits[fruits.length - 1];
// Or: let last = fruits.at(-1);
// Length property
console.log(fruits.length); // 5
// Modifying by index
fruits[1] = 'blueberry';
console.log(fruits); // ['apple', 'blueberry', 'orange', 'grape', 'mango']
// Adding beyond length creates sparse array
fruits[10] = 'kiwi';
console.log(fruits.length); // 11
console.log(fruits[5]); // undefined
➕ Adding and Removing Elements
End of Array
let numbers = [1, 2, 3];
// push - add to end (mutates, returns new length)
numbers.push(4);
console.log(numbers); // [1, 2, 3, 4]
numbers.push(5, 6, 7);
console.log(numbers); // [1, 2, 3, 4, 5, 6, 7]
// pop - remove from end (mutates, returns removed element)
let last = numbers.pop();
console.log(last); // 7
console.log(numbers); // [1, 2, 3, 4, 5, 6]
Beginning of Array
let numbers = [1, 2, 3];
// unshift - add to beginning (mutates, returns new length)
numbers.unshift(0);
console.log(numbers); // [0, 1, 2, 3]
numbers.unshift(-2, -1);
console.log(numbers); // [-2, -1, 0, 1, 2, 3]
// shift - remove from beginning (mutates, returns removed element)
let first = numbers.shift();
console.log(first); // -2
console.log(numbers); // [-1, 0, 1, 2, 3]
Middle of Array
let fruits = ['apple', 'banana', 'orange'];
// splice(start, deleteCount, ...items)
// Remove 1 element at index 1
fruits.splice(1, 1);
console.log(fruits); // ['apple', 'orange']
// Add elements at index 1
fruits.splice(1, 0, 'grape', 'mango');
console.log(fruits); // ['apple', 'grape', 'mango', 'orange']
// Replace elements
fruits.splice(1, 2, 'kiwi');
console.log(fruits); // ['apple', 'kiwi', 'orange']
// Remove from index to end
let removed = fruits.splice(1);
console.log(removed); // ['kiwi', 'orange']
console.log(fruits); // ['apple']
🔄 Array Methods - Iteration
forEach
// Execute function for each element
let numbers = [1, 2, 3, 4, 5];
numbers.forEach((num) => {
console.log(num * 2);
});
// With index and array
numbers.forEach((num, index, arr) => {
console.log(`Index ${index}: ${num}`);
});
// Note: forEach cannot be stopped (no break/return)
// Returns undefined
map
// Transform each element, returns new array
let numbers = [1, 2, 3, 4, 5];
let doubled = numbers.map(n => n * 2);
console.log(doubled); // [2, 4, 6, 8, 10]
let squared = numbers.map(n => n ** 2);
console.log(squared); // [1, 4, 9, 16, 25]
// With objects
let users = [
{ name: 'John', age: 25 },
{ name: 'Jane', age: 30 }
];
let names = users.map(user => user.name);
console.log(names); // ['John', 'Jane']
// With index
let indexed = numbers.map((n, i) => `${i}: ${n}`);
console.log(indexed); // ['0: 1', '1: 2', '2: 3', '3: 4', '4: 5']
filter
// Keep elements that pass test, returns new array
let numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
let evens = numbers.filter(n => n % 2 === 0);
console.log(evens); // [2, 4, 6, 8, 10]
let greaterThanFive = numbers.filter(n => n > 5);
console.log(greaterThanFive); // [6, 7, 8, 9, 10]
// With objects
let users = [
{ name: 'John', age: 25, active: true },
{ name: 'Jane', age: 30, active: false },
{ name: 'Bob', age: 20, active: true }
];
let activeUsers = users.filter(user => user.active);
console.log(activeUsers); // John and Bob
let adults = users.filter(user => user.age >= 25);
console.log(adults); // John and Jane
reduce
// Reduce array to single value
let numbers = [1, 2, 3, 4, 5];
// Sum
let sum = numbers.reduce((acc, n) => acc + n, 0);
console.log(sum); // 15
// Product
let product = numbers.reduce((acc, n) => acc * n, 1);
console.log(product); // 120
// Maximum value
let max = numbers.reduce((acc, n) => Math.max(acc, n));
console.log(max); // 5
// Count occurrences
let items = ['apple', 'banana', 'apple', 'orange', 'banana', 'apple'];
let counts = items.reduce((acc, item) => {
acc[item] = (acc[item] || 0) + 1;
return acc;
}, {});
console.log(counts); // { apple: 3, banana: 2, orange: 1 }
// Group by property
let users = [
{ name: 'John', role: 'admin' },
{ name: 'Jane', role: 'user' },
{ name: 'Bob', role: 'admin' }
];
let grouped = users.reduce((acc, user) => {
if (!acc[user.role]) acc[user.role] = [];
acc[user.role].push(user);
return acc;
}, {});
console.log(grouped);
// { admin: [John, Bob], user: [Jane] }
// reduceRight - process from right to left
let reversed = numbers.reduceRight((acc, n) => {
acc.push(n);
return acc;
}, []);
console.log(reversed); // [5, 4, 3, 2, 1]
🔎 Searching and Testing
find and findIndex
let numbers = [1, 5, 10, 15, 20];
// find - returns first element that passes test
let found = numbers.find(n => n > 10);
console.log(found); // 15
// findIndex - returns index of first match
let index = numbers.findIndex(n => n > 10);
console.log(index); // 3
// findLast and findLastIndex (ES2023)
let last = numbers.findLast(n => n > 10);
console.log(last); // 20
let lastIndex = numbers.findLastIndex(n => n > 10);
console.log(lastIndex); // 4
// With objects
let users = [
{ id: 1, name: 'John' },
{ id: 2, name: 'Jane' },
{ id: 3, name: 'Bob' }
];
let user = users.find(u => u.id === 2);
console.log(user); // { id: 2, name: 'Jane' }
includes, indexOf, lastIndexOf
let fruits = ['apple', 'banana', 'orange', 'banana', 'grape'];
// includes - check if element exists (ES2016)
console.log(fruits.includes('banana')); // true
console.log(fruits.includes('kiwi')); // false
// indexOf - first index of element (-1 if not found)
console.log(fruits.indexOf('banana')); // 1
console.log(fruits.indexOf('kiwi')); // -1
// lastIndexOf - last index of element
console.log(fruits.lastIndexOf('banana')); // 3
// With start position
console.log(fruits.indexOf('banana', 2)); // 3 (search from index 2)
some and every
let numbers = [1, 2, 3, 4, 5];
// some - test if ANY element passes
console.log(numbers.some(n => n > 3)); // true
console.log(numbers.some(n => n > 10)); // false
// every - test if ALL elements pass
console.log(numbers.every(n => n > 0)); // true
console.log(numbers.every(n => n > 3)); // false
// Practical examples
let users = [
{ name: 'John', age: 25 },
{ name: 'Jane', age: 17 },
{ name: 'Bob', age: 30 }
];
let hasMinor = users.some(u => u.age < 18);
console.log(hasMinor); // true
let allAdults = users.every(u => u.age >= 18);
console.log(allAdults); // false
✂️ Slicing and Joining
slice
// Extract portion (doesn't mutate original)
let fruits = ['apple', 'banana', 'orange', 'grape', 'mango'];
// slice(start, end) - end not included
let sliced = fruits.slice(1, 3);
console.log(sliced); // ['banana', 'orange']
console.log(fruits); // Original unchanged
// From index to end
console.log(fruits.slice(2)); // ['orange', 'grape', 'mango']
// Negative indices (from end)
console.log(fruits.slice(-2)); // ['grape', 'mango']
console.log(fruits.slice(1, -1)); // ['banana', 'orange', 'grape']
// Copy array
let copy = fruits.slice();
// Or: let copy = [...fruits];
concat
// Merge arrays (doesn't mutate originals)
let arr1 = [1, 2, 3];
let arr2 = [4, 5, 6];
let arr3 = [7, 8, 9];
let merged = arr1.concat(arr2);
console.log(merged); // [1, 2, 3, 4, 5, 6]
// Multiple arrays
let all = arr1.concat(arr2, arr3);
console.log(all); // [1, 2, 3, 4, 5, 6, 7, 8, 9]
// With values
let extended = arr1.concat(4, 5, [6, 7]);
console.log(extended); // [1, 2, 3, 4, 5, 6, 7]
// Modern alternative: spread
let spread = [...arr1, ...arr2, ...arr3];
console.log(spread); // [1, 2, 3, 4, 5, 6, 7, 8, 9]
join and split
// join - array to string
let fruits = ['apple', 'banana', 'orange'];
console.log(fruits.join()); // 'apple,banana,orange'
console.log(fruits.join(', ')); // 'apple, banana, orange'
console.log(fruits.join(' - ')); // 'apple - banana - orange'
console.log(fruits.join('')); // 'applebananaorange'
// split - string to array (String method)
let text = 'apple,banana,orange';
let arr = text.split(',');
console.log(arr); // ['apple', 'banana', 'orange']
let sentence = 'Hello World JavaScript';
let words = sentence.split(' ');
console.log(words); // ['Hello', 'World', 'JavaScript']
let chars = 'hello'.split('');
console.log(chars); // ['h', 'e', 'l', 'l', 'o']
🔀 Sorting and Reversing
// reverse - reverses array (mutates)
let numbers = [1, 2, 3, 4, 5];
numbers.reverse();
console.log(numbers); // [5, 4, 3, 2, 1]
// toReversed - returns new reversed array (ES2023)
let original = [1, 2, 3];
let reversed = original.toReversed();
console.log(original); // [1, 2, 3] (unchanged)
console.log(reversed); // [3, 2, 1]
// sort - sorts array (mutates)
let fruits = ['banana', 'apple', 'orange', 'grape'];
fruits.sort();
console.log(fruits); // ['apple', 'banana', 'grape', 'orange']
// Sort numbers (default converts to strings!)
let nums = [10, 5, 40, 25, 1000, 1];
nums.sort();
console.log(nums); // [1, 10, 1000, 25, 40, 5] (wrong!)
// Proper numeric sort
nums.sort((a, b) => a - b); // Ascending
console.log(nums); // [1, 5, 10, 25, 40, 1000]
nums.sort((a, b) => b - a); // Descending
console.log(nums); // [1000, 40, 25, 10, 5, 1]
// Sort objects
let users = [
{ name: 'John', age: 30 },
{ name: 'Jane', age: 25 },
{ name: 'Bob', age: 35 }
];
// By age
users.sort((a, b) => a.age - b.age);
console.log(users); // Jane(25), John(30), Bob(35)
// By name
users.sort((a, b) => a.name.localeCompare(b.name));
console.log(users); // Bob, Jane, John
// toSorted - returns new sorted array (ES2023)
let original2 = [3, 1, 4, 1, 5];
let sorted = original2.toSorted((a, b) => a - b);
console.log(original2); // [3, 1, 4, 1, 5] (unchanged)
console.log(sorted); // [1, 1, 3, 4, 5]
🎯 Advanced Array Methods
flat and flatMap
// flat - flatten nested arrays (ES2019)
let nested = [1, [2, 3], [4, [5, 6]]];
console.log(nested.flat()); // [1, 2, 3, 4, [5, 6]] (1 level)
console.log(nested.flat(2)); // [1, 2, 3, 4, 5, 6] (2 levels)
console.log(nested.flat(Infinity)); // Fully flatten
// flatMap - map then flat (1 level)
let numbers = [1, 2, 3];
let doubled = numbers.flatMap(n => [n, n * 2]);
console.log(doubled); // [1, 2, 2, 4, 3, 6]
// Practical: split sentences to words
let sentences = ['Hello world', 'JavaScript is fun'];
let words = sentences.flatMap(s => s.split(' '));
console.log(words); // ['Hello', 'world', 'JavaScript', 'is', 'fun']
fill and copyWithin
// fill - fill with static value (mutates)
let arr1 = [1, 2, 3, 4, 5];
arr1.fill(0);
console.log(arr1); // [0, 0, 0, 0, 0]
// fill(value, start, end)
let arr2 = [1, 2, 3, 4, 5];
arr2.fill(0, 2, 4);
console.log(arr2); // [1, 2, 0, 0, 5]
// Create array with initial value
let zeros = new Array(5).fill(0);
console.log(zeros); // [0, 0, 0, 0, 0]
// copyWithin - copy part of array (mutates)
let arr3 = [1, 2, 3, 4, 5];
arr3.copyWithin(0, 3); // Copy from index 3 to index 0
console.log(arr3); // [4, 5, 3, 4, 5]
Array.isArray
// Check if value is array
console.log(Array.isArray([1, 2, 3])); // true
console.log(Array.isArray('hello')); // false
console.log(Array.isArray({ a: 1 })); // false
console.log(Array.isArray(null)); // false
// Why not typeof?
console.log(typeof [1, 2, 3]); // 'object' (not helpful!)
// Practical: input validation
function processArray(input) {
if (!Array.isArray(input)) {
throw new Error('Input must be an array');
}
return input.map(n => n * 2);
}
💡 Practical Examples
Remove Duplicates
// Using Set
let numbers = [1, 2, 2, 3, 3, 3, 4, 5, 5];
let unique = [...new Set(numbers)];
console.log(unique); // [1, 2, 3, 4, 5]
// Using filter
let unique2 = numbers.filter((n, i, arr) => arr.indexOf(n) === i);
console.log(unique2); // [1, 2, 3, 4, 5]
// Objects by property
let users = [
{ id: 1, name: 'John' },
{ id: 2, name: 'Jane' },
{ id: 1, name: 'John' }
];
let uniqueUsers = users.filter((u, i, arr) =>
arr.findIndex(user => user.id === u.id) === i
);
Chunk Array
// Split array into chunks
function chunk(arr, size) {
return Array.from({ length: Math.ceil(arr.length / size) }, (_, i) =>
arr.slice(i * size, i * size + size)
);
}
let numbers = [1, 2, 3, 4, 5, 6, 7, 8];
console.log(chunk(numbers, 3));
// [[1, 2, 3], [4, 5, 6], [7, 8]]
Shuffle Array
// Fisher-Yates shuffle
function shuffle(arr) {
let shuffled = [...arr];
for (let i = shuffled.length - 1; i > 0; i--) {
let j = Math.floor(Math.random() * (i + 1));
[shuffled[i], shuffled[j]] = [shuffled[j], shuffled[i]];
}
return shuffled;
}
let cards = [1, 2, 3, 4, 5];
console.log(shuffle(cards)); // Random order
Pagination
function paginate(arr, page, perPage) {
const start = (page - 1) * perPage;
const end = start + perPage;
return {
data: arr.slice(start, end),
page: page,
perPage: perPage,
total: arr.length,
totalPages: Math.ceil(arr.length / perPage)
};
}
let items = Array.from({ length: 25 }, (_, i) => i + 1);
console.log(paginate(items, 2, 10));
// { data: [11-20], page: 2, perPage: 10, total: 25, totalPages: 3 }
Array Statistics
function getStats(arr) {
const sum = arr.reduce((acc, n) => acc + n, 0);
const avg = sum / arr.length;
const sorted = [...arr].sort((a, b) => a - b);
const min = sorted[0];
const max = sorted[sorted.length - 1];
const median = sorted[Math.floor(sorted.length / 2)];
return { sum, avg, min, max, median };
}
let scores = [85, 92, 78, 95, 88];
console.log(getStats(scores));
// { sum: 438, avg: 87.6, min: 78, max: 95, median: 88 }
🎯 Key Takeaways
- Creation: Use array literal [...] for creating arrays
- map: Transform each element, returns new array
- filter: Keep elements that pass test, returns new array
- reduce: Combine elements into single value (sum, max, grouping)
- find/findIndex: Get first element/index that matches condition
- some/every: Test if any/all elements pass condition
- Immutability: Methods like slice, concat, spread don't mutate original
- Mutation: push, pop, splice, sort, reverse modify original array