Working with Arrays in JavaScript

Understanding JavaScript Arrays and Their Basic Methods

What Are Arrays?

Imagine you have a shopping list. Instead of writing separate variables for each item, arrays let you store multiple values in a single, organized container. Arrays are like a train with multiple cars, where each car holds a different piece of data.

graph TD A[Array] --> B["0: Apple"] A --> C["1: Banana"] A --> D["2: Orange"] A --> E["3: Grape"] style A fill:#f9f,stroke:#333,stroke-width:4px style B fill:#bfb,stroke:#333,stroke-width:2px style C fill:#bfb,stroke:#333,stroke-width:2px style D fill:#bfb,stroke:#333,stroke-width:2px style E fill:#bfb,stroke:#333,stroke-width:2px

Creating Arrays

Just like there are different ways to make a sandwich, there are multiple ways to create arrays in JavaScript:

// Method 1: Array literal (most common)
const fruits = ['apple', 'banana', 'orange'];

// Method 2: Array constructor
const numbers = new Array(1, 2, 3, 4, 5);

// Method 3: Empty array
const emptyBasket = [];

// Arrays can hold mixed data types
const mixedBag = ['text', 42, true, null, { name: 'John' }];

Real-World Example: Shopping Cart

// A shopping cart in an e-commerce site
const shoppingCart = [
    { product: 'Laptop', price: 999.99, quantity: 1 },
    { product: 'Mouse', price: 29.99, quantity: 2 },
    { product: 'Keyboard', price: 89.99, quantity: 1 }
];

Array Properties and Access

Arrays are like apartment buildings - each item has its own "apartment number" (index), starting from 0:

const colors = ['red', 'green', 'blue', 'yellow'];

// Accessing elements
console.log(colors[0]);      // 'red' (first element)
console.log(colors[2]);      // 'blue' (third element)

// Length property - like counting floors in a building
console.log(colors.length);  // 4

// Modifying elements - like repainting an apartment
colors[1] = 'lime';
console.log(colors);        // ['red', 'lime', 'blue', 'yellow']

// Accessing last element
console.log(colors[colors.length - 1]); // 'yellow'

Essential Array Methods

Arrays come with built-in superpowers (methods) that help you manipulate data:

Push and Pop - Adding/Removing from the End

const playlist = ['Song A', 'Song B'];

// push() - Like adding songs to end of playlist
playlist.push('Song C');
console.log(playlist);  // ['Song A', 'Song B', 'Song C']

// pop() - Like removing the last song
const lastSong = playlist.pop();
console.log(lastSong);  // 'Song C'
console.log(playlist);  // ['Song A', 'Song B']

Unshift and Shift - Adding/Removing from the Start

const queue = ['Person 2', 'Person 3'];

// unshift() - Like someone cutting in line
queue.unshift('Person 1');
console.log(queue);  // ['Person 1', 'Person 2', 'Person 3']

// shift() - Like the first person being served
const firstPerson = queue.shift();
console.log(firstPerson);  // 'Person 1'
console.log(queue);        // ['Person 2', 'Person 3']

Finding Elements in Arrays

Finding items in arrays is like searching for a book in a library:

const books = ['JavaScript', 'Python', 'Java', 'C++', 'Python'];

// indexOf() - Find first occurrence (like finding first copy of book)
console.log(books.indexOf('Python'));     // 1
console.log(books.indexOf('Ruby'));       // -1 (not found)

// lastIndexOf() - Find last occurrence
console.log(books.lastIndexOf('Python')); // 4

// includes() - Check if item exists (like asking "Do you have this book?")
console.log(books.includes('Java'));      // true
console.log(books.includes('Go'));        // false

Slice and Splice - Array Surgery

Think of arrays as cakes that you can cut and modify:

slice() - Taking a Piece Without Changing Original

const cake = ['layer1', 'layer2', 'layer3', 'layer4', 'layer5'];

// Get a slice (doesn't modify original)
const middlePiece = cake.slice(1, 4);
console.log(middlePiece);  // ['layer2', 'layer3', 'layer4']
console.log(cake);         // Original unchanged

splice() - Surgery on the Array

const ingredients = ['flour', 'sugar', 'eggs', 'butter', 'salt'];

// Remove 2 items starting at index 1
const removed = ingredients.splice(1, 2);
console.log(removed);      // ['sugar', 'eggs']
console.log(ingredients);  // ['flour', 'butter', 'salt']

// Add items at index 1
ingredients.splice(1, 0, 'milk', 'vanilla');
console.log(ingredients);  // ['flour', 'milk', 'vanilla', 'butter', 'salt']

Real-World Applications

Todo List Application

let todoList = [];

function addTask(task) {
    todoList.push({
        id: Date.now(),
        task: task,
        completed: false,
        createdAt: new Date()
    });
}

function completeTask(id) {
    const taskIndex = todoList.findIndex(task => task.id === id);
    if (taskIndex !== -1) {
        todoList[taskIndex].completed = true;
    }
}

function removeTask(id) {
    todoList = todoList.filter(task => task.id !== id);
}

// Usage
addTask('Learn JavaScript arrays');
addTask('Practice array methods');
console.log(todoList);

completeTask(todoList[0].id);
console.log(todoList);

Playlist Manager

class PlaylistManager {
    constructor() {
        this.playlist = [];
        this.currentIndex = 0;
    }

    addSong(song) {
        this.playlist.push(song);
    }

    removeSong(index) {
        if (index >= 0 && index < this.playlist.length) {
            this.playlist.splice(index, 1);
        }
    }

    shuffle() {
        // Fisher-Yates shuffle algorithm
        for (let i = this.playlist.length - 1; i > 0; i--) {
            const j = Math.floor(Math.random() * (i + 1));
            [this.playlist[i], this.playlist[j]] = [this.playlist[j], this.playlist[i]];
        }
    }

    getCurrentSong() {
        return this.playlist[this.currentIndex];
    }

    nextSong() {
        this.currentIndex = (this.currentIndex + 1) % this.playlist.length;
        return this.getCurrentSong();
    }
}

// Usage
const myPlaylist = new PlaylistManager();
myPlaylist.addSong({ title: 'Song 1', artist: 'Artist A' });
myPlaylist.addSong({ title: 'Song 2', artist: 'Artist B' });
console.log(myPlaylist.getCurrentSong());

Performance Tips

// Good performance practice
const bigArray = new Array(1000); // Pre-allocated

// Caching length in loops
for (let i = 0, len = bigArray.length; i < len; i++) {
    // Process array elements
}

// Avoid sparse arrays
const sparse = [1, 2, 3];
delete sparse[1];  // Creates a hole - bad!
console.log(sparse);  // [1, empty, 3]

// Better approach
const dense = [1, 2, 3];
dense.splice(1, 1);  // Removes and shifts
console.log(dense);  // [1, 3]

Practice Exercises

  1. Create a function that reverses an array without using the reverse() method
  2. Build a function that removes duplicate values from an array
  3. Create a function that finds the second largest number in an array
  4. Implement a function that rotates an array by n positions

Exercise Solutions (Try First!)

Click to see solutions
// 1. Reverse array without reverse()
function reverseArray(arr) {
    const result = [];
    for (let i = arr.length - 1; i >= 0; i--) {
        result.push(arr[i]);
    }
    return result;
}

// 2. Remove duplicates
function removeDuplicates(arr) {
    return [...new Set(arr)];
    // or
    // return arr.filter((item, index) => arr.indexOf(item) === index);
}

// 3. Find second largest
function secondLargest(arr) {
    if (arr.length < 2) return null;
    
    let first = -Infinity;
    let second = -Infinity;
    
    for (const num of arr) {
        if (num > first) {
            second = first;
            first = num;
        } else if (num > second && num < first) {
            second = num;
        }
    }
    
    return second === -Infinity ? null : second;
}

// 4. Rotate array
function rotateArray(arr, n) {
    const len = arr.length;
    n = n % len; // Handle n greater than length
    
    return [...arr.slice(n), ...arr.slice(0, n)];
}

Common Pitfalls to Avoid

  • Off-by-one errors: Remember arrays start at index 0
  • Modifying while iterating: Can cause unexpected behavior
  • Reference vs. Value: Arrays are reference types
  • Sparse arrays: Avoid using delete on array elements
// Pitfall: Reference types
const original = [1, 2, 3];
const copy = original;  // This is a reference, not a copy!
copy[0] = 99;
console.log(original);  // [99, 2, 3] - Original is modified!

// Solution: Create actual copies
const actualCopy1 = [...original];  // Spread operator
const actualCopy2 = original.slice();  // slice method
const actualCopy3 = Array.from(original);  // Array.from

Summary

Arrays are fundamental data structures in JavaScript that:

Next up: We'll explore object literals and how they complement arrays in JavaScript!