JavaScript Arrays
Arrays are one of the most important data structures in JavaScript, used to store and manipulate ordered collections of data. JavaScript provides rich array methods that make array operations very convenient and powerful. In this chapter, we will learn in depth about arrays and their various operation methods in JavaScript.
What is an Array
An array is a special type of object used to store ordered collections of elements. Each element in an array has a numeric index, starting from 0.
Array Characteristics
- Ordered: Elements are arranged in insertion order
- Index Access: Elements are accessed by numeric index
- Dynamic: Size can change dynamically
- Mixed Types: Can store different types of data
- Reference Type: Arrays are objects, passed by reference
Creating Arrays
Array Literal
javascript
// Empty array
const emptyArray = [];
// Array with elements
const fruits = ["apple", "banana", "orange"];
const numbers = [1, 2, 3, 4, 5];
const mixed = [1, "hello", true, null, { name: "John" }];
// Multi-dimensional array
const matrix = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
];
console.log(fruits[0]); // "apple"
console.log(numbers[2]); // 3
console.log(matrix[1][2]); // 6Array Constructor
javascript
// Create empty array
const arr1 = new Array();
const arr2 = new Array(5); // Create array of length 5
// Create array with elements
const arr3 = new Array(1, 2, 3);
const arr4 = new Array("apple", "banana", "orange");
// Note: Single number argument creates array of that length
const arr5 = new Array(3);
console.log(arr5.length); // 3
// Use Array.of() to avoid this issue
const arr6 = Array.of(3);
console.log(arr6); // [3]Array.from()
javascript
// Create array from array-like object
function example() {
return Array.from(arguments);
}
const argsArray = example(1, 2, 3);
console.log(argsArray); // [1, 2, 3]
// Create array from string
const strArray = Array.from("hello");
console.log(strArray); // ["h", "e", "l", "l", "o"]
// Create array from Set
const set = new Set([1, 2, 3, 2, 1]);
const setArray = Array.from(set);
console.log(setArray); // [1, 2, 3]
// Using map function
const doubled = Array.from([1, 2, 3], x => x * 2);
console.log(doubled); // [2, 4, 6]
// Create and initialize array of specified length
const zeros = Array.from({ length: 5 }, () => 0);
console.log(zeros); // [0, 0, 0, 0, 0]
const indices = Array.from({ length: 5 }, (_, index) => index);
console.log(indices); // [0, 1, 2, 3, 4]Basic Array Operations
Accessing and Modifying Elements
javascript
const colors = ["red", "green", "blue"];
// Access elements
console.log(colors[0]); // "red"
console.log(colors[colors.length - 1]); // "blue" (last element)
// Modify elements
colors[1] = "yellow";
console.log(colors); // ["red", "yellow", "blue"]
// Add elements
colors[3] = "purple";
console.log(colors); // ["red", "yellow", "blue", "purple"]Array Length
javascript
const arr = [1, 2, 3];
console.log(arr.length); // 3
// Modify length property
arr.length = 5;
console.log(arr); // [1, 2, 3, undefined, undefined]
arr.length = 2;
console.log(arr); // [1, 2]
// Clear array
arr.length = 0;
console.log(arr); // []Array Methods
Adding and Removing Elements
javascript
const fruits = ["apple", "banana"];
// push() - add to end
const newLength = fruits.push("orange");
console.log(fruits); // ["apple", "banana", "orange"]
// pop() - remove from end
const lastFruit = fruits.pop();
console.log(lastFruit); // "orange"
// unshift() - add to beginning
fruits.unshift("grape");
console.log(fruits); // ["grape", "apple", "banana"]
// shift() - remove from beginning
const firstFruit = fruits.shift();
console.log(firstFruit); // "grape"
// splice() - add/remove elements at any position
const vegetables = ["carrot", "potato", "onion"];
// At index 1, remove 1 element, add "tomato" and "cucumber"
const removed = vegetables.splice(1, 1, "tomato", "cucumber");
console.log(vegetables); // ["carrot", "tomato", "cucumber", "onion"]
console.log(removed); // ["potato"]Concatenation and Copying
javascript
const arr1 = [1, 2, 3];
const arr2 = [4, 5, 6];
// concat() - join arrays
const combined = arr1.concat(arr2);
console.log(combined); // [1, 2, 3, 4, 5, 6]
// Spread operator concatenation
const combined2 = [...arr1, ...arr2];
console.log(combined2); // [1, 2, 3, 4, 5, 6]
// slice() - extract array section (shallow copy)
const numbers = [1, 2, 3, 4, 5];
const slice1 = numbers.slice(1, 4);
console.log(slice1); // [2, 3, 4]
// Copy entire array
const copy = numbers.slice();
console.log(copy); // [1, 2, 3, 4, 5]
// Spread operator copy
const copy2 = [...numbers];Array Search
javascript
const fruits = ["apple", "banana", "orange", "apple", "grape"];
// indexOf() - find first occurrence index
console.log(fruits.indexOf("apple")); // 0
console.log(fruits.indexOf("watermelon")); // -1 (not found)
// lastIndexOf() - find last occurrence index
console.log(fruits.lastIndexOf("apple")); // 3
// includes() - check if element exists
console.log(fruits.includes("banana")); // true
// find() - find first element matching condition
const numbers = [1, 5, 10, 15, 20];
const found = numbers.find(num => num > 10);
console.log(found); // 15
const users = [
{ id: 1, name: "John" },
{ id: 2, name: "Jane" },
{ id: 3, name: "Alice" }
];
const user = users.find(u => u.id === 2);
console.log(user); // { id: 2, name: "Jane" }
// findIndex() - find index of first matching element
const index = numbers.findIndex(num => num > 10);
console.log(index); // 3
// filter() - filter elements matching condition
const filtered = numbers.filter(num => num > 10);
console.log(filtered); // [15, 20]Array Iteration
javascript
const fruits = ["apple", "banana", "orange"];
// for loop
for (let i = 0; i < fruits.length; i++) {
console.log(`${i}: ${fruits[i]}`);
}
// for...of loop
for (const fruit of fruits) {
console.log(fruit);
}
// forEach() method
fruits.forEach((fruit, index) => {
console.log(`${index}: ${fruit}`);
});
// entries() - get key-value pairs
for (const [index, fruit] of fruits.entries()) {
console.log(`${index}: ${fruit}`);
}Array Transformation
javascript
const numbers = [1, 2, 3, 4, 5];
// map() - transform each element
const doubled = numbers.map(num => num * 2);
console.log(doubled); // [2, 4, 6, 8, 10]
const users = [
{ name: "John", age: 25 },
{ name: "Jane", age: 30 },
{ name: "Alice", age: 35 }
];
const names = users.map(user => user.name);
console.log(names); // ["John", "Jane", "Alice"]
// flat() - flatten array
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]
// 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"]
// join() - join elements into string
const fruits = ["apple", "banana", "orange"];
console.log(fruits.join(", ")); // "apple, banana, orange"Array Sorting
javascript
// sort() - sort array
const fruits = ["banana", "apple", "orange"];
fruits.sort();
console.log(fruits); // ["apple", "banana", "orange"]
const numbers = [10, 2, 30, 4];
numbers.sort();
console.log(numbers); // [10, 2, 30, 4] (string comparison)
// Numeric sorting
numbers.sort((a, b) => a - b);
console.log(numbers); // [2, 4, 10, 30] (ascending)
numbers.sort((a, b) => b - a);
console.log(numbers); // [30, 10, 4, 2] (descending)
// Object sorting
const users = [
{ name: "John", age: 25 },
{ name: "Jane", age: 30 },
{ name: "Alice", age: 20 }
];
// Sort by age
users.sort((a, b) => a.age - b.age);
// Sort by name
users.sort((a, b) => a.name.localeCompare(b.name));
// reverse() - reverse array
const arr = [1, 2, 3, 4, 5];
arr.reverse();
console.log(arr); // [5, 4, 3, 2, 1]Array Aggregation
javascript
const numbers = [1, 2, 3, 4, 5];
// reduce() - accumulate calculation
const sum = numbers.reduce((accumulator, current) => accumulator + current, 0);
console.log(sum); // 15
// Find maximum value
const max = numbers.reduce((max, current) => Math.max(max, current));
console.log(max); // 5
// Count element occurrences
const fruits = ["apple", "banana", "apple", "orange", "banana", "apple"];
const count = fruits.reduce((acc, fruit) => {
acc[fruit] = (acc[fruit] || 0) + 1;
return acc;
}, {});
console.log(count); // { apple: 3, banana: 2, orange: 1 }
// every() - check if all elements satisfy condition
const allPositive = numbers.every(num => num > 0);
console.log(allPositive); // true
// some() - check if any element satisfies condition
const hasEven = numbers.some(num => num % 2 === 0);
console.log(hasEven); // trueModern Array Methods
ES2022 New Methods
javascript
const numbers = [1, 2, 3, 4, 5];
// at() - supports negative index
console.log(numbers.at(0)); // 1
console.log(numbers.at(-1)); // 5 (last element)
console.log(numbers.at(-2)); // 4 (second to last)
// findLast() - find from end
const lastEven = numbers.findLast(num => num % 2 === 0);
console.log(lastEven); // 4
// findLastIndex() - find index from end
const lastEvenIndex = numbers.findLastIndex(num => num % 2 === 0);
console.log(lastEvenIndex); // 3Array Best Practices
1. Avoid Sparse Arrays
javascript
// Bad practice
const sparse = new Array(3);
sparse[0] = "first";
sparse[2] = "third";
console.log(sparse); // ["first", empty, "third"]
// Good practice
const dense = Array.from({ length: 3 }, () => undefined);
dense[0] = "first";
dense[2] = "third";2. Use Functional Methods
javascript
const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
// Bad practice - using for loop
function getEvenSquares(numbers) {
const result = [];
for (let i = 0; i < numbers.length; i++) {
if (numbers[i] % 2 === 0) {
result.push(numbers[i] * numbers[i]);
}
}
return result;
}
// Good practice - using functional methods
const evenSquares = numbers
.filter(num => num % 2 === 0)
.map(num => num * num);
console.log(evenSquares); // [4, 16, 36, 64, 100]3. Method Chaining
javascript
const products = [
{ name: "Laptop", price: 1000, category: "Electronics" },
{ name: "Phone", price: 500, category: "Electronics" },
{ name: "Book", price: 20, category: "Books" },
{ name: "Headphones", price: 100, category: "Electronics" }
];
// Chain method calls to process data
const result = products
.filter(product => product.category === "Electronics")
.filter(product => product.price > 100)
.map(product => ({
...product,
discountPrice: product.price * 0.9
}))
.sort((a, b) => a.discountPrice - b.discountPrice)
.map(product => product.name);
console.log(result); // ["Phone", "Laptop"]Practical Examples
Array Utility Class
javascript
class ArrayUtils {
// Chunk array
static chunk(array, size) {
const chunks = [];
for (let i = 0; i < array.length; i += size) {
chunks.push(array.slice(i, i + size));
}
return chunks;
}
// Array difference
static difference(array, ...values) {
const flatValues = values.flat();
return array.filter(item => !flatValues.includes(item));
}
// Array intersection
static intersection(array, ...values) {
const flatValues = values.flat();
return array.filter(item => flatValues.includes(item));
}
// Array union
static union(array, ...values) {
const flatValues = values.flat();
return [...new Set([...array, ...flatValues])];
}
// Unique array (supports objects)
static unique(array, keyFunction) {
if (keyFunction) {
const seen = new Set();
return array.filter(item => {
const key = keyFunction(item);
if (seen.has(key)) {
return false;
}
seen.add(key);
return true;
});
}
return [...new Set(array)];
}
// Shuffle array
static shuffle(array) {
const result = [...array];
for (let i = result.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[result[i], result[j]] = [result[j], result[i]];
}
return result;
}
// Sum array
static sum(array, keyFunction) {
if (keyFunction) {
return array.reduce((sum, item) => sum + keyFunction(item), 0);
}
return array.reduce((sum, num) => sum + num, 0);
}
// Range
static range(start, end, step = 1) {
const result = [];
for (let i = start; i < end; i += step) {
result.push(i);
}
return result;
}
}
// Usage examples
const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
console.log(ArrayUtils.chunk(numbers, 3));
// [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10]]
console.log(ArrayUtils.difference([1, 2, 3, 4, 5], [2, 4])); // [1, 3, 5]
console.log(ArrayUtils.intersection([1, 2, 3], [2, 3, 4])); // [2, 3]
console.log(ArrayUtils.union([1, 2], [2, 3], [3, 4])); // [1, 2, 3, 4]
console.log(ArrayUtils.shuffle([1, 2, 3, 4, 5])); // Random order
console.log(ArrayUtils.sum([1, 2, 3, 4, 5])); // 15
console.log(ArrayUtils.range(0, 10, 2)); // [0, 2, 4, 6, 8]Summary
Key points about JavaScript arrays:
- Creation Methods: Literal, constructor, Array.from(), Array.of()
- Basic Operations: Access, modify, add, remove elements
- Iteration Methods: forEach(), for...of, entries(), keys(), values()
- Transformation Methods: map(), filter(), reduce(), flat(), flatMap()
- Search Methods: find(), findIndex(), indexOf(), includes()
- Sort Methods: sort(), reverse()
- Concatenation Methods: concat(), slice(), join()
- Modern Methods: at(), findLast(), findLastIndex()
- Best Practices: Avoid sparse arrays, use functional methods, performance optimization
- Practical Applications: Data processing pipelines, utility classes
Arrays are fundamental to JavaScript programming, and mastering various array methods and techniques is crucial for improving programming efficiency. In the next chapter, we will learn about the JavaScript Number object.