frontend / javascript core / array-methods.md

JavaScript Array Methods Interview Questions & Answers

5 interview angles 19 min read source

JavaScript Array Methods Interview Questions & Answers

JavaScript arrays come with a rich set of built-in methods for manipulation, iteration, and transformation. Understanding these methods is crucial for efficient array operations in JavaScript.

Table of Contents


Array Creation Methods

1. What are the different ways to create arrays in JavaScript?

Multiple ways to create arrays:

// 1. Array literal (most common)
const arr1 = [1, 2, 3, 4, 5];
const arr2 = ["apple", "banana", "orange"];
const arr3 = [1, "hello", true, { name: "John" }];

// 2. Array constructor
const arr4 = new Array(1, 2, 3, 4, 5);
const arr5 = new Array(5); // Creates array with 5 empty slots

// 3. Array.from()
const arr6 = Array.from("hello"); // ["h", "e", "l", "l", "o"]
const arr7 = Array.from({ length: 5 }, (_, i) => i); // [0, 1, 2, 3, 4]

// 4. Array.of()
const arr8 = Array.of(1, 2, 3, 4, 5);
const arr9 = Array.of(5); // [5] (different from new Array(5))

// 5. Spread operator
const arr10 = [...arr1, 6, 7, 8];

// 6. Destructuring assignment
const [a, b, c] = [1, 2, 3];
const arr11 = [a, b, c]; // [1, 2, 3]

2. What is the difference between Array() and Array.of()?

Key differences:

// Array() constructor
console.log(new Array(5));     // [empty × 5] (sparse array)
console.log(new Array(1, 2));  // [1, 2]
console.log(new Array(1));     // [1]

// Array.of() method
console.log(Array.of(5));      // [5] (single element)
console.log(Array.of(1, 2));   // [1, 2]
console.log(Array.of(1));      // [1]

// When they're the same
console.log(new Array(1, 2, 3)); // [1, 2, 3]
console.log(Array.of(1, 2, 3));  // [1, 2, 3]

Use cases:

// Array() - when you want to create array with specific length
const emptyArray = new Array(10); // [empty × 10]

// Array.of() - when you want to create array with specific values
const singleElementArray = Array.of(42); // [42]

3. How does Array.from() work and when would you use it?

Array.from() creates a new array from an array-like or iterable object.

// 1. From string
const chars = Array.from("hello"); // ["h", "e", "l", "l", "o"]

// 2. From Set
const set = new Set([1, 2, 3, 3, 4]);
const uniqueArray = Array.from(set); // [1, 2, 3, 4]

// 3. From Map
const map = new Map([["a", 1], ["b", 2]]);
const mapArray = Array.from(map); // [["a", 1], ["b", 2]]

// 4. From array-like object
const arrayLike = { 0: "a", 1: "b", 2: "c", length: 3 };
const array = Array.from(arrayLike); // ["a", "b", "c"]

// 5. With mapping function
const numbers = Array.from({ length: 5 }, (_, i) => i * 2); // [0, 2, 4, 6, 8]

// 6. From arguments object
function createArray() {
    return Array.from(arguments);
}
console.log(createArray(1, 2, 3)); // [1, 2, 3]

Advanced use cases:

// Create range of numbers
const range = (start, end) => Array.from(
    { length: end - start + 1 },
    (_, i) => start + i
);
console.log(range(1, 5)); // [1, 2, 3, 4, 5]

// Remove duplicates
const removeDuplicates = (arr) => Array.from(new Set(arr));
console.log(removeDuplicates([1, 2, 2, 3, 3, 4])); // [1, 2, 3, 4]

// Convert NodeList to Array
const elements = document.querySelectorAll("div");
const elementArray = Array.from(elements);

Array Access Methods

4. How do you access array elements and what are the bounds?

Array element access:

const arr = ["apple", "banana", "orange", "grape"];

// Basic access
console.log(arr[0]);     // "apple"
console.log(arr[2]);     // "orange"
console.log(arr[-1]);    // undefined (no negative indexing)

// Access last element
console.log(arr[arr.length - 1]); // "grape"

// Check if index exists
console.log(arr.hasOwnProperty(1)); // true
console.log(arr.hasOwnProperty(10)); // false

// Using at() method (ES2022+)
console.log(arr.at(0));      // "apple"
console.log(arr.at(-1));     // "grape" (negative indexing)
console.log(arr.at(-2));     // "orange"
console.log(arr.at(10));     // undefined

5. What are the differences between array access methods?

Comparison of access methods:

const arr = ["a", "b", "c", "d"];

// Traditional indexing
console.log(arr[0]);     // "a"
console.log(arr[-1]);    // undefined

// at() method (ES2022+)
console.log(arr.at(0));  // "a"
console.log(arr.at(-1)); // "d"

// slice() for range access
console.log(arr.slice(1, 3)); // ["b", "c"]
console.log(arr.slice(-2));   // ["c", "d"]

// Destructuring
const [first, second, ...rest] = arr;
console.log(first);  // "a"
console.log(second); // "b"
console.log(rest);   // ["c", "d"]

Array Modification Methods

6. What are the mutating array methods?

Methods that modify the original array:

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

// push() - add to end
arr.push(6);
console.log(arr); // [1, 2, 3, 4, 5, 6]

// pop() - remove from end
const last = arr.pop();
console.log(last); // 6
console.log(arr);  // [1, 2, 3, 4, 5]

// unshift() - add to beginning
arr.unshift(0);
console.log(arr); // [0, 1, 2, 3, 4, 5]

// shift() - remove from beginning
const first = arr.shift();
console.log(first); // 0
console.log(arr);   // [1, 2, 3, 4, 5]

// splice() - add/remove at specific position
arr.splice(2, 1, "new"); // Remove 1 element at index 2, insert "new"
console.log(arr); // [1, 2, "new", 4, 5]

// reverse() - reverse array
arr.reverse();
console.log(arr); // [5, 4, "new", 2, 1]

// sort() - sort array
arr.sort();
console.log(arr); // [1, 2, 4, 5, "new"]

// fill() - fill array with value
arr.fill(0, 1, 3); // Fill with 0 from index 1 to 3 (exclusive)
console.log(arr); // [1, 0, 0, 5, "new"]

7. How does splice() work and what are its parameters?

splice() changes the contents of an array by removing or replacing existing elements and/or adding new elements.

Syntax: array.splice(start, deleteCount, item1, item2, ...)

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

// Remove elements
const removed = arr.splice(1, 2); // Remove 2 elements starting at index 1
console.log(removed); // [2, 3]
console.log(arr);     // [1, 4, 5]

// Add elements
arr.splice(1, 0, "a", "b"); // Add "a", "b" at index 1, remove 0 elements
console.log(arr); // [1, "a", "b", 4, 5]

// Replace elements
arr.splice(2, 1, "c"); // Replace 1 element at index 2 with "c"
console.log(arr); // [1, "a", "c", 4, 5]

// Remove from end
arr.splice(-2); // Remove last 2 elements
console.log(arr); // [1, "a", "c"]

// Remove all elements
arr.splice(0); // Remove all elements
console.log(arr); // []

Common use cases:

// Remove element by index
function removeAtIndex(arr, index) {
    arr.splice(index, 1);
    return arr;
}

// Insert element at index
function insertAtIndex(arr, index, element) {
    arr.splice(index, 0, element);
    return arr;
}

// Replace element at index
function replaceAtIndex(arr, index, element) {
    arr.splice(index, 1, element);
    return arr;
}

8. What are the non-mutating array methods?

Methods that return new arrays without modifying the original:

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

// concat() - combine arrays
const combined = original.concat([6, 7], [8, 9]);
console.log(combined); // [1, 2, 3, 4, 5, 6, 7, 8, 9]
console.log(original); // [1, 2, 3, 4, 5] (unchanged)

// slice() - extract portion
const portion = original.slice(1, 4); // Extract from index 1 to 4 (exclusive)
console.log(portion); // [2, 3, 4]
console.log(original); // [1, 2, 3, 4, 5] (unchanged)

// Spread operator
const spread = [...original, 6, 7];
console.log(spread); // [1, 2, 3, 4, 5, 6, 7]
console.log(original); // [1, 2, 3, 4, 5] (unchanged)

// Array.from()
const copy = Array.from(original);
console.log(copy); // [1, 2, 3, 4, 5]
console.log(original); // [1, 2, 3, 4, 5] (unchanged)

Array Search Methods

9. How do you search for elements in arrays?

Different search methods:

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

// indexOf() - find first occurrence
console.log(arr.indexOf(2));     // 1
console.log(arr.indexOf(10));    // -1 (not found)

// lastIndexOf() - find last occurrence
console.log(arr.lastIndexOf(2)); // 5

// includes() - check if element exists
console.log(arr.includes(3));    // true
console.log(arr.includes(10));   // false

// find() - find first element that satisfies condition
const found = arr.find(x => x > 3);
console.log(found); // 4

// findIndex() - find index of first element that satisfies condition
const foundIndex = arr.findIndex(x => x > 3);
console.log(foundIndex); // 3

// some() - check if any element satisfies condition
console.log(arr.some(x => x > 5)); // true

// every() - check if all elements satisfy condition
console.log(arr.every(x => x > 0)); // true
console.log(arr.every(x => x > 3)); // false

10. What are the differences between search methods?

Comparison of search methods:

Method Returns Stops at Use case
indexOf() Index or -1 First match Find exact value
lastIndexOf() Index or -1 Last match Find last occurrence
includes() Boolean First match Check existence
find() Element or undefined First match Find with condition
findIndex() Index or -1 First match Find index with condition
some() Boolean First match Check if any satisfy
every() Boolean First false Check if all satisfy

Examples:

const users = [
    { id: 1, name: "John", age: 30 },
    { id: 2, name: "Jane", age: 25 },
    { id: 3, name: "Bob", age: 35 }
];

// Find user by id
const user = users.find(u => u.id === 2);
console.log(user); // { id: 2, name: "Jane", age: 25 }

// Check if any user is over 30
const hasOlderUser = users.some(u => u.age > 30);
console.log(hasOlderUser); // true

// Check if all users are adults
const allAdults = users.every(u => u.age >= 18);
console.log(allAdults); // true

// Find index of user with specific name
const janeIndex = users.findIndex(u => u.name === "Jane");
console.log(janeIndex); // 1

Array Iteration Methods

11. What are the different array iteration methods?

Common iteration methods:

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

// forEach() - execute function for each element
arr.forEach((item, index) => {
    console.log(`Index ${index}: ${item}`);
});

// for...of loop
for (const item of arr) {
    console.log(item);
}

// for...in loop (iterates over indices)
for (const index in arr) {
    console.log(`Index ${index}: ${arr[index]}`);
}

// Traditional for loop
for (let i = 0; i < arr.length; i++) {
    console.log(`Index ${i}: ${arr[i]}`);
}

// map() - transform each element
const doubled = arr.map(x => x * 2);
console.log(doubled); // [2, 4, 6, 8, 10]

// filter() - select elements that satisfy condition
const evens = arr.filter(x => x % 2 === 0);
console.log(evens); // [2, 4]

// reduce() - accumulate values
const sum = arr.reduce((acc, curr) => acc + curr, 0);
console.log(sum); // 15

12. How does forEach() work and when would you use it?

forEach() executes a provided function once for each array element.

const fruits = ["apple", "banana", "orange"];

// Basic usage
fruits.forEach((fruit, index) => {
    console.log(`${index}: ${fruit}`);
});

// With object context
const user = {
    name: "John",
    logFruits: function(fruits) {
        fruits.forEach(function(fruit) {
            console.log(`${this.name} likes ${fruit}`);
        }, this); // 'this' context
    }
};

user.logFruits(fruits);

// Side effects (mutating external variables)
let total = 0;
const numbers = [1, 2, 3, 4, 5];

numbers.forEach(num => {
    total += num;
});

console.log(total); // 15

// Cannot break out of forEach
numbers.forEach(num => {
    if (num === 3) {
        return; // Only skips current iteration, doesn't break
    }
    console.log(num);
});

When to use forEach:

  • When you need to perform side effects
  • When you don’t need to return a value
  • When you want simple iteration without breaking

When NOT to use forEach:

  • When you need to break out of the loop
  • When you need to return a value
  • When you need async operations (use for…of instead)

Array Transformation Methods

13. How does map() work and what are its use cases?

map() creates a new array with the results of calling a function for every array element.

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

// Basic transformation
const doubled = numbers.map(x => x * 2);
console.log(doubled); // [2, 4, 6, 8, 10]

// Transform objects
const users = [
    { name: "John", age: 30 },
    { name: "Jane", age: 25 },
    { name: "Bob", age: 35 }
];

const names = users.map(user => user.name);
console.log(names); // ["John", "Jane", "Bob"]

const userInfo = users.map(user => ({
    name: user.name,
    isAdult: user.age >= 18
}));
console.log(userInfo); // [{ name: "John", isAdult: true }, ...]

// With index parameter
const indexed = numbers.map((num, index) => `${index}: ${num}`);
console.log(indexed); // ["0: 1", "1: 2", "2: 3", "3: 4", "4: 5"]

// Chaining with other methods
const result = numbers
    .filter(x => x % 2 === 0)
    .map(x => x * 2)
    .reduce((acc, curr) => acc + curr, 0);
console.log(result); // 12 (2*2 + 4*2 = 12)

Common use cases:

// Convert data types
const strings = ["1", "2", "3"];
const numbers = strings.map(Number);
console.log(numbers); // [1, 2, 3]

// Extract specific properties
const products = [
    { id: 1, name: "Laptop", price: 999 },
    { id: 2, name: "Phone", price: 599 },
    { id: 3, name: "Tablet", price: 399 }
];

const prices = products.map(p => p.price);
console.log(prices); // [999, 599, 399]

// Create HTML elements
const items = ["apple", "banana", "orange"];
const htmlList = items.map(item => `<li>${item}</li>`).join('');
console.log(htmlList); // "<li>apple</li><li>banana</li><li>orange</li>"

14. How does filter() work and what are its use cases?

filter() creates a new array with elements that pass a test.

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

// Basic filtering
const evens = numbers.filter(x => x % 2 === 0);
console.log(evens); // [2, 4, 6, 8, 10]

const odds = numbers.filter(x => x % 2 !== 0);
console.log(odds); // [1, 3, 5, 7, 9]

// Filter objects
const users = [
    { name: "John", age: 30, active: true },
    { name: "Jane", age: 25, active: false },
    { name: "Bob", age: 35, active: true },
    { name: "Alice", age: 20, active: true }
];

const activeUsers = users.filter(user => user.active);
console.log(activeUsers); // [{ name: "John", age: 30, active: true }, ...]

const adults = users.filter(user => user.age >= 18);
console.log(adults); // All users (all are adults)

// Multiple conditions
const activeAdults = users.filter(user => user.active && user.age >= 25);
console.log(activeAdults); // [{ name: "John", age: 30, active: true }, { name: "Bob", age: 35, active: true }]

// Remove falsy values
const mixed = [0, 1, false, 2, "", 3, null, undefined, 4];
const truthy = mixed.filter(Boolean);
console.log(truthy); // [1, 2, 3, 4]

// Remove duplicates
const duplicates = [1, 2, 2, 3, 3, 4];
const unique = duplicates.filter((item, index, arr) => arr.indexOf(item) === index);
console.log(unique); // [1, 2, 3, 4]

Advanced filtering:

// Filter by search term
const products = [
    { name: "Laptop", category: "Electronics" },
    { name: "Book", category: "Education" },
    { name: "Phone", category: "Electronics" },
    { name: "Pen", category: "Office" }
];

function filterBySearch(items, searchTerm) {
    return items.filter(item =>
        item.name.toLowerCase().includes(searchTerm.toLowerCase()) ||
        item.category.toLowerCase().includes(searchTerm.toLowerCase())
    );
}

console.log(filterBySearch(products, "electronics")); // Laptop and Phone
console.log(filterBySearch(products, "book")); // Book

Array Reduction Methods

15. How does reduce() work and what are its use cases?

reduce() executes a reducer function on each element, resulting in a single output value.

Syntax: array.reduce(callback(accumulator, currentValue, index, array), initialValue)

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

// Basic sum
const sum = numbers.reduce((acc, curr) => acc + curr, 0);
console.log(sum); // 15

// Without initial value (uses first element as initial)
const sum2 = numbers.reduce((acc, curr) => acc + curr);
console.log(sum2); // 15

// Find maximum
const max = numbers.reduce((acc, curr) => Math.max(acc, curr));
console.log(max); // 5

// Count 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 }

// Group by property
const users = [
    { name: "John", age: 30, city: "NYC" },
    { name: "Jane", age: 25, city: "LA" },
    { name: "Bob", age: 35, city: "NYC" },
    { name: "Alice", age: 20, city: "LA" }
];

const groupedByCity = users.reduce((acc, user) => {
    if (!acc[user.city]) {
        acc[user.city] = [];
    }
    acc[user.city].push(user);
    return acc;
}, {});

console.log(groupedByCity);
// {
//   NYC: [{ name: "John", age: 30, city: "NYC" }, { name: "Bob", age: 35, city: "NYC" }],
//   LA: [{ name: "Jane", age: 25, city: "LA" }, { name: "Alice", age: 20, city: "LA" }]
// }

Advanced use cases:

// Flatten nested arrays
const nested = [[1, 2], [3, 4], [5, 6]];
const flattened = nested.reduce((acc, curr) => acc.concat(curr), []);
console.log(flattened); // [1, 2, 3, 4, 5, 6]

// Remove duplicates
const duplicates = [1, 2, 2, 3, 3, 4];
const unique = duplicates.reduce((acc, curr) => {
    if (!acc.includes(curr)) {
        acc.push(curr);
    }
    return acc;
}, []);
console.log(unique); // [1, 2, 3, 4]

// Create object from array
const pairs = [["name", "John"], ["age", 30], ["city", "NYC"]];
const obj = pairs.reduce((acc, [key, value]) => {
    acc[key] = value;
    return acc;
}, {});
console.log(obj); // { name: "John", age: 30, city: "NYC" }

16. What is reduceRight() and when would you use it?

reduceRight() works like reduce() but processes the array from right to left.

const numbers = [1, 2, 3, 4];

// Regular reduce (left to right)
const leftToRight = numbers.reduce((acc, curr) => acc - curr);
console.log(leftToRight); // -8 (1-2-3-4)

// reduceRight (right to left)
const rightToLeft = numbers.reduceRight((acc, curr) => acc - curr);
console.log(rightToLeft); // -2 (4-3-2-1)

// String operations
const words = ["Hello", "World", "JavaScript"];
const sentence = words.reduceRight((acc, word) => acc + " " + word);
console.log(sentence); // "JavaScript World Hello"

// Function composition
const functions = [
    x => x + 1,
    x => x * 2,
    x => x - 3
];

const composed = functions.reduceRight((acc, fn) => fn(acc), 5);
console.log(composed); // 9 ((5-3)*2+1 = 9)

Array Sorting Methods

17. How does sort() work and how do you customize it?

sort() sorts the elements of an array in place and returns the sorted array.

const fruits = ["banana", "apple", "orange", "grape"];

// Default sort (alphabetical)
fruits.sort();
console.log(fruits); // ["apple", "banana", "grape", "orange"]

// Numeric sort (incorrect)
const numbers = [10, 5, 8, 1, 2];
numbers.sort();
console.log(numbers); // [1, 10, 2, 5, 8] (lexicographic sort)

// Numeric sort (correct)
numbers.sort((a, b) => a - b);
console.log(numbers); // [1, 2, 5, 8, 10]

// Reverse sort
numbers.sort((a, b) => b - a);
console.log(numbers); // [10, 8, 5, 2, 1]

// Sort objects
const users = [
    { name: "John", age: 30 },
    { name: "Jane", age: 25 },
    { name: "Bob", age: 35 }
];

// Sort by age
users.sort((a, b) => a.age - b.age);
console.log(users); // [{ name: "Jane", age: 25 }, { name: "John", age: 30 }, { name: "Bob", age: 35 }]

// Sort by name
users.sort((a, b) => a.name.localeCompare(b.name));
console.log(users); // [{ name: "Bob", age: 35 }, { name: "Jane", age: 25 }, { name: "John", age: 30 }]

// Multi-criteria sort
const products = [
    { name: "Laptop", price: 999, rating: 4.5 },
    { name: "Phone", price: 599, rating: 4.8 },
    { name: "Tablet", price: 399, rating: 4.2 },
    { name: "Laptop", price: 899, rating: 4.3 }
];

// Sort by name, then by price
products.sort((a, b) => {
    if (a.name !== b.name) {
        return a.name.localeCompare(b.name);
    }
    return a.price - b.price;
});

Sort comparison function rules:

  • Return negative: a comes before b
  • Return positive: b comes before a
  • Return zero: order unchanged
// Custom sort functions
const sortBy = (property) => (a, b) => a[property] - b[property];
const sortByString = (property) => (a, b) => a[property].localeCompare(b[property]);

// Usage
users.sort(sortBy('age'));
products.sort(sortByString('name'));

Advanced Array Concepts

18. How do you work with sparse arrays?

Sparse arrays are arrays with gaps (undefined elements).

// Creating sparse arrays
const sparse = [1, , 3, , 5]; // Gaps at indices 1 and 3
const sparse2 = new Array(5); // Creates array with 5 undefined elements

console.log(sparse.length);   // 5
console.log(sparse[1]);       // undefined
console.log(sparse[2]);       // 3

// Checking for gaps
console.log(sparse.hasOwnProperty(1)); // false
console.log(sparse.hasOwnProperty(2)); // true

// Iterating over sparse arrays
sparse.forEach((item, index) => {
    console.log(`Index ${index}: ${item}`);
}); // Only logs defined elements

// Using for...of (skips undefined)
for (const item of sparse) {
    console.log(item);
}

// Using for...in (includes all indices)
for (const index in sparse) {
    console.log(`Index ${index}: ${sparse[index]}`);
}

// Converting sparse to dense
const dense = sparse.filter(() => true);
console.log(dense); // [1, 3, 5]

19. How do you implement common array operations?

Common array operations implementation:

// Remove element by value
function removeByValue(arr, value) {
    const index = arr.indexOf(value);
    if (index > -1) {
        arr.splice(index, 1);
    }
    return arr;
}

// Remove element by index
function removeByIndex(arr, index) {
    arr.splice(index, 1);
    return arr;
}

// Insert element at index
function insertAtIndex(arr, index, element) {
    arr.splice(index, 0, element);
    return arr;
}

// Shuffle array
function shuffle(arr) {
    const shuffled = [...arr];
    for (let i = shuffled.length - 1; i > 0; i--) {
        const j = Math.floor(Math.random() * (i + 1));
        [shuffled[i], shuffled[j]] = [shuffled[j], shuffled[i]];
    }
    return shuffled;
}

// Chunk array
function chunk(arr, size) {
    const chunks = [];
    for (let i = 0; i < arr.length; i += size) {
        chunks.push(arr.slice(i, i + size));
    }
    return chunks;
}

// Flatten nested arrays
function flatten(arr) {
    return arr.reduce((acc, val) =>
        Array.isArray(val) ? acc.concat(flatten(val)) : acc.concat(val),
    []);
}

// Remove duplicates
function unique(arr) {
    return [...new Set(arr)];
}

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

console.log(shuffle(numbers));           // Random order
console.log(chunk(numbers, 3));          // [[1,2,3], [4,5,6], [7,8,9], [10]]
console.log(unique([1,2,2,3,3,4]));      // [1,2,3,4]
console.log(flatten([[1,2], [3,4], [5]])); // [1,2,3,4,5]

20. How do you handle array performance considerations?

Performance tips for array operations:

// 1. Use appropriate methods
const arr = [1, 2, 3, 4, 5];

// Good - for simple iteration
arr.forEach(item => console.log(item));

// Good - for transformation
const doubled = arr.map(x => x * 2);

// Good - for filtering
const evens = arr.filter(x => x % 2 === 0);

// Good - for accumulation
const sum = arr.reduce((acc, curr) => acc + curr, 0);

// 2. Avoid nested loops when possible
const users = [
    { id: 1, name: "John" },
    { id: 2, name: "Jane" },
    { id: 3, name: "Bob" }
];

// Bad - O(n²)
function findUserBad(users, name) {
    for (let i = 0; i < users.length; i++) {
        for (let j = 0; j < users.length; j++) {
            if (users[i].name === name) return users[i];
        }
    }
}

// Good - O(n)
function findUserGood(users, name) {
    return users.find(user => user.name === name);
}

// 3. Use Set for unique values
const duplicates = [1, 2, 2, 3, 3, 4];
const unique = [...new Set(duplicates)]; // Fast

// 4. Use Map for key-value lookups
const userMap = new Map(users.map(user => [user.id, user]));
const user = userMap.get(1); // O(1) lookup

// 5. Avoid creating new arrays unnecessarily
// Bad
const result = arr.map(x => x * 2).filter(x => x > 5).slice(0, 3);

// Better - single pass
const result2 = arr.reduce((acc, x) => {
    const doubled = x * 2;
    if (doubled > 5 && acc.length < 3) {
        acc.push(doubled);
    }
    return acc;
}, []);

Additional Resources


Mastering array methods is essential for efficient JavaScript development. Practice these methods to write cleaner and more maintainable code.

Interview angle

  • “Which array methods mutate?” - sort, reverse, splice, push/pop/shift/unshift, fill, copyWithin. ES2023 added copying counterparts - toSorted, toReversed, toSpliced, with - which is what you want in React, where mutating state in place skips the re-render.
  • map or forEach?” - map returns a new array and should be used for its return value; forEach returns undefined and exists for side effects. map with no use of the result is a smell reviewers pick up on.
  • “How does sort compare by default?” - by string conversion, so [10, 9, 1].sort() gives [1, 10, 9]. Always pass a comparator for numbers.
  • find versus filter?” - find short-circuits on the first match and returns the element; filter scans everything and returns an array. Using filter(...)[0] on a large array does needless work.
  • “How do you group items?” - Object.groupBy / Map.groupBy (ES2024). Before that, a reduce into an object, which is the one legitimately common use of reduce.