beginner Step 5 of 20

Arrays and Array Methods

JavaScript Programming

Arrays and Array Methods

Arrays are ordered collections of values and one of the most frequently used data structures in JavaScript. Unlike arrays in some other languages, JavaScript arrays are dynamic (they can grow and shrink), can hold mixed types, and come with an incredibly rich set of built-in methods for transforming, filtering, searching, and reducing data. Modern JavaScript array methods like map(), filter(), and reduce() enable a functional programming style that produces clean, expressive, and maintainable code.

Creating and Accessing Arrays

// Creating arrays
const fruits = ["apple", "banana", "cherry"];
const numbers = [1, 2, 3, 4, 5];
const mixed = [1, "hello", true, null, { name: "Alice" }];
const empty = [];
const fromConstructor = new Array(5).fill(0);  // [0, 0, 0, 0, 0]

// Accessing elements
console.log(fruits[0]);      // "apple"
console.log(fruits[2]);      // "cherry"
console.log(fruits.at(-1));  // "cherry" (ES2022 — negative index)

// Length
console.log(fruits.length);  // 3

// Check if array
console.log(Array.isArray(fruits));  // true
console.log(Array.isArray("hello")); // false

Mutating Methods

const arr = [1, 2, 3, 4, 5];

// Add/remove from end
arr.push(6);         // [1,2,3,4,5,6] — returns new length
arr.pop();           // [1,2,3,4,5] — returns removed element (6)

// Add/remove from beginning
arr.unshift(0);      // [0,1,2,3,4,5] — returns new length
arr.shift();         // [1,2,3,4,5] — returns removed element (0)

// splice — add/remove at any position
const colors = ["red", "green", "blue", "yellow"];
colors.splice(1, 2);              // Remove 2 items at index 1 → ["red", "yellow"]
colors.splice(1, 0, "purple");    // Insert at index 1 → ["red", "purple", "yellow"]
colors.splice(1, 1, "orange", "pink");  // Replace 1 item → ["red", "orange", "pink", "yellow"]

// Sorting
const nums = [3, 1, 4, 1, 5, 9, 2, 6];
nums.sort((a, b) => a - b);  // Ascending: [1, 1, 2, 3, 4, 5, 6, 9]
nums.sort((a, b) => b - a);  // Descending: [9, 6, 5, 4, 3, 2, 1, 1]

// Reverse
nums.reverse();

Non-Mutating Methods (Functional)

const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

// map — transform each element
const doubled = numbers.map(n => n * 2);
// [2, 4, 6, 8, 10, 12, 14, 16, 18, 20]

// filter — keep elements that pass a test
const evens = numbers.filter(n => n % 2 === 0);
// [2, 4, 6, 8, 10]

// find — get first matching element
const firstBig = numbers.find(n => n > 5);
// 6

// findIndex — get index of first match
const idx = numbers.findIndex(n => n > 5);
// 5

// some — does ANY element pass the test?
const hasNegative = numbers.some(n => n < 0);
// false

// every — do ALL elements pass the test?
const allPositive = numbers.every(n => n > 0);
// true

// includes — does the array contain this value?
console.log(numbers.includes(5));  // true

// reduce — accumulate values into one result
const sum = numbers.reduce((acc, n) => acc + n, 0);
// 55

const max = numbers.reduce((a, b) => a > b ? a : b);
// 10

// flat — flatten nested arrays
const nested = [[1, 2], [3, [4, 5]]];
console.log(nested.flat());    // [1, 2, 3, [4, 5]]
console.log(nested.flat(2));   // [1, 2, 3, 4, 5]

// flatMap — map then flatten
const sentences = ["Hello World", "Goodbye Moon"];
const words = sentences.flatMap(s => s.split(" "));
// ["Hello", "World", "Goodbye", "Moon"]

// slice — extract portion (does not mutate)
const subset = numbers.slice(2, 5);  // [3, 4, 5]
const copy = numbers.slice();        // Full copy

Chaining Array Methods

// Process data with method chaining
const users = [
    { name: "Alice", age: 30, active: true },
    { name: "Bob", age: 17, active: true },
    { name: "Charlie", age: 25, active: false },
    { name: "Diana", age: 22, active: true },
    { name: "Eve", age: 19, active: true }
];

// Get names of active adult users, sorted alphabetically
const result = users
    .filter(u => u.active && u.age >= 18)
    .map(u => u.name)
    .sort();

console.log(result);  // ["Alice", "Diana", "Eve"]

// Calculate average age of active users
const avgAge = users
    .filter(u => u.active)
    .reduce((sum, u, _, arr) => sum + u.age / arr.length, 0);

console.log(avgAge.toFixed(1));  // "21.6"

// Group by property using reduce
const grouped = users.reduce((groups, user) => {
    const key = user.active ? "active" : "inactive";
    groups[key] = groups[key] || [];
    groups[key].push(user.name);
    return groups;
}, {});

console.log(grouped);
// { active: ["Alice", "Bob", "Diana", "Eve"], inactive: ["Charlie"] }
Pro tip: Prefer non-mutating methods (map, filter, slice) over mutating ones (splice, sort, push) when working with state in frameworks like React. If you need to sort without mutating, use [...arr].sort() or arr.toSorted() (ES2023). Method chaining with filter().map().reduce() creates clean data transformation pipelines.

Key Takeaways

  • map() transforms elements, filter() selects elements, and reduce() accumulates into a single value.
  • Use find() for the first match and some()/every() for boolean tests on arrays.
  • Method chaining (.filter().map().sort()) creates readable data processing pipelines.
  • Prefer non-mutating methods and spread syntax ([...arr]) to avoid side effects.
  • Use Array.isArray() to reliably check if a value is an array, since typeof [] returns "object".