Arrays (very important)
Arrays (very important)
"Arrays are the most fundamental data structure in DSA. Nearly every algorithm you learn will involve one."
Part 1: Declaring and Accessing Arrays
An array is an ordered collection of values stored under a single variable name. Each value has an index — a number that tells you its position. Indexes start at 0, not 1.
Creating arrays
// Array literal (most common way)
let fruits = ["apple", "banana", "mango"];
let scores = [85, 92, 78, 100];
let mixed = [1, "hello", true]; // Arrays can hold any type
// Empty array
let empty = [];
// Array with a fixed size (filled with undefined)
let fixed = new Array(5);Indexing — 0-based access
The first element is at index 0, the last is at index length - 1.
let nums = [10, 20, 30, 40, 50];
// index: 0 1 2 3 4
console.log(nums[0]); // 10 (first)
console.log(nums[2]); // 30
console.log(nums[nums.length - 1]); // 50 (last)
// ❌ Index out of bounds returns undefined, not an error
console.log(nums[10]); // undefined
// Modifying an element
nums[1] = 99;
console.log(nums); // [10, 99, 30, 40, 50]Array length
let arr = [1, 2, 3, 4, 5];
console.log(arr.length); // 5
// length is live — updates automatically
arr.push(6);
console.log(arr.length); // 6Part 2: Iterating Arrays
for loop — index-based (most DSA-friendly)
The go-to loop for arrays in DSA. Because you have access to the index i, you can read, write, compare neighbours (nums[i] vs nums[i+1]), or run two pointers at once. Use this whenever the position matters.
let nums = [3, 7, 1, 9, 4];
for (let i = 0; i < nums.length; i++) {
console.log(`index ${i}: ${nums[i]}`);
}
// index 0: 3
// index 1: 7 ... etcfor...of — clean value iteration
Gives you each value directly without managing an index variable. Best when you only need the value and don't care about its position — for example, summing all elements or printing them. Not suitable when you need to modify the array or compare elements by index.
let fruits = ["apple", "banana", "mango"];
for (let fruit of fruits) {
console.log(fruit);
}
// apple
// banana
// mangoforEach — functional style
A built-in method that runs a callback function for each element. Cleaner syntax than a for loop when you don't need to break early (you can't use break or continue inside forEach). It also gives you the index as the second argument if you need it.
let scores = [85, 92, 78];
scores.forEach((score, index) => {
console.log(`Student ${index + 1}: ${score}`);
});
// Student 1: 85
// Student 2: 92
// Student 3: 78
// ❌ break/continue don't work inside forEach
// ✅ Use a regular for loop if you need early exitCommon array methods
These are the methods you'll reach for constantly — memorise their names and what they return.
let arr = [3, 1, 4, 1, 5];
arr.push(9); // Add to end → [3,1,4,1,5,9]
arr.pop(); // Remove from end → [3,1,4,1,5]
arr.unshift(0); // Add to front → [0,3,1,4,1,5]
arr.shift(); // Remove from front → [3,1,4,1,5]
arr.sort((a, b) => a - b); // Sort ascending → [1,1,3,4,5]
arr.reverse(); // Reverse in place
// Slice — returns a portion (non-destructive)
let sliced = arr.slice(1, 3); // index 1 to 2
// indexOf — find position of a value (-1 if not found)
console.log(arr.indexOf(4)); // position of 4Part 3: 2D Arrays
A 2D array is an array of arrays — perfect for grids, matrices, and board problems. It's one of the most common structures in DSA interviews.
Creating and accessing a 2D array
A 2D array is written as an array where each element is itself an array — one inner array per row. To access an element you use two indexes: matrix[row][col]. Think of it as "which row first, then which column inside that row." Row and column indexes both start at 0.
let matrix = [
[1, 2, 3], // row 0
[4, 5, 6], // row 1
[7, 8, 9] // row 2
];
console.log(matrix[0][0]); // 1 (row 0, col 0)
console.log(matrix[1][2]); // 6 (row 1, col 2)
console.log(matrix[2][1]); // 8 (row 2, col 1)
// Number of rows
console.log(matrix.length); // 3
// Number of columns in row 0
console.log(matrix[0].length); // 3Traversing a 2D array (nested loop)
To visit every cell you need two loops — the outer loop moves through rows, the inner loop moves through columns within each row. For a matrix of size R × C this visits every element exactly once, giving you O(R × C) time — or O(n²) when it's square. This pattern is the foundation for grid problems like flood fill, path finding, and island counting.
let grid = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
];
for (let row = 0; row < grid.length; row++) {
for (let col = 0; col < grid[row].length; col++) {
process.stdout.write(grid[row][col] + " ");
}
console.log(); // move to next line after each row
}
// 1 2 3
// 4 5 6
// 7 8 9Dynamic arrays — flexible size
A static array has a fixed size set at creation — you can't add more elements later. A dynamic array grows automatically as you add items. In JavaScript all arrays are dynamic by default. In other languages you opt in: ArrayList in Java,list in Python, vector in C++. Under the hood, when the array runs out of space it allocates a bigger block and copies everything over — that's why push is O(1) on average but occasionally O(n).
// JavaScript — always dynamic
let dynamic = [];
for (let i = 0; i < 5; i++) {
dynamic.push(i * i); // grows automatically
}
console.log(dynamic); // [0, 1, 4, 9, 16]
// Java equivalent:
// ArrayList<Integer> list = new ArrayList<>();
// list.add(value);
// Python equivalent:
// nums = []
// nums.append(value)