Skip to content

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

  1. Ordered: Elements are arranged in insertion order
  2. Index Access: Elements are accessed by numeric index
  3. Dynamic: Size can change dynamically
  4. Mixed Types: Can store different types of data
  5. 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]); // 6

Array 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];
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); // true

Modern 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); // 3

Array 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:

  1. Creation Methods: Literal, constructor, Array.from(), Array.of()
  2. Basic Operations: Access, modify, add, remove elements
  3. Iteration Methods: forEach(), for...of, entries(), keys(), values()
  4. Transformation Methods: map(), filter(), reduce(), flat(), flatMap()
  5. Search Methods: find(), findIndex(), indexOf(), includes()
  6. Sort Methods: sort(), reverse()
  7. Concatenation Methods: concat(), slice(), join()
  8. Modern Methods: at(), findLast(), findLastIndex()
  9. Best Practices: Avoid sparse arrays, use functional methods, performance optimization
  10. 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.

Content is for learning and research only.