JavaScript Arrays
Complete array guide for interviews — creation, destructuring, mutating vs non-mutating methods, higher-order functions, ES2023 immutability, and practice problems with solutions.
Introduction
Arrays are the most-used data structure in JavaScript — from React state and API responses to algorithm interviews. This guide covers core concepts, interview-ready explanations, and hands-on practice problems with solutions.
Course Reference
Quick index
1. Creation & access
Create an array
const salad = ['🍅', '🍄', '🥦', '🥒', '🌽', '🥕', '🥑']
const anotherSalad = new Array('🍅', '🍄', '🥦', '🥒', '🌽', '🥕', '🥑')Get elements by index
const salad = ['🍅', '🍄', '🥦', '🥒', '🌽', '🥕', '🥑']
salad[0] // '🍅'
salad[2] // '🥦'
salad[5] // '🥕'
// Last element via length
const len = salad.length
salad[len - 1] // '🥑'
salad[len - 3] // '🌽'Loop with for
const salad = ['🍅', '🍄', '🥦', '🥒', '🌽', '🥕', '🥑']
for (let i = 0; i < salad.length; i++) {
console.log(`Element at index ${i} is ${salad[i]}`)
}2. Add, remove, clone
Add elements
const salad = ['🍅', '🍄', '🥦', '🥒', '🌽', '🥕', '🥑']
salad.push('🥜') // add at end — mutates
salad.unshift('🥜') // add at front — mutatesRemove elements
const salad = ['🍅', '🍄', '🥦', '🥒', '🌽', '🥕', '🥑']
salad.pop() // removes last — returns '🥑'
console.log(salad) // ['🍅', '🍄', '🥦', '🥒', '🌽', '🥕']Shallow clone with slice()
const salad = ['🍅', '🍄', '🥦', '🥒', '🌽', '🥕', '🥑']
const saladCopy = salad.slice()
console.log(saladCopy) // same values
salad === saladCopy // false — different reference3. Array.isArray
Array.isArray(['🍅', '🍄', '🥦']) // true
Array.isArray('🍅') // false
Array.isArray({ tomato: '🍅' }) // false
Array.isArray([]) // true4. Destructuring, rest & spread
Basic destructuring
let [tomato, mushroom, carrot] = ['🍅', '🍄', '🥕']
console.log(tomato, mushroom, carrot) // 🍅 🍄 🥕
// Equivalent without destructuring
let vegetables = ['🍅', '🍄', '🥕']
let tomato2 = vegetables[0]
let mushroom2 = vegetables[1]
let carrot2 = vegetables[2]Default values
let [tomato, mushroom = '🍄'] = ['🍅']
console.log(tomato) // '🍅'
console.log(mushroom) // '🍄' — default appliedSkip a value
let [tomato, , carrot] = ['🍅', '🍄', '🥕']
console.log(tomato) // '🍅'
console.log(carrot) // '🥕'Nested destructuring
let fruits = ['🍈', '🍍', '🍌', '🍉', ['🍅', '🍄', '🥕']]
const veg = fruits[4] // ['🍅', '🍄', '🥕']
const carrot = veg[2] // '🥕'
fruits[4][2] // '🥕'
let [, , , , [, , carrot2]] = ['🍈', '🍍', '🍌', '🍉', ['🍅', '🍄', '🥕']]Rest parameter
const [tomato, mushroom, ...rest] = ['🍅', '🍄', '🥦', '🥒', '🌽', '🥕', '🥑']
console.log(tomato) // '🍅'
console.log(mushroom) // '🍄'
console.log(rest) // ['🥦', '🥒', '🌽', '🥕', '🥑']Spread operator — clone & merge
const salad = ['🍅', '🍄', '🥦', '🥒', '🌽', '🥕', '🥑']
const saladCloned = [...salad]
salad === saladCloned // false
// Merge arrays
const emotion = ['🙂', '😔']
const veggies = ['🥦', '🥒', '🌽', '🥕']
const emotionalVeggies = [...emotion, ...veggies]
// ['🙂', '😔', '🥦', '🥒', '🌽', '🥕']Swap values
let first = '😔'
let second = '🙂'
;[first, second] = [second, first]
console.log(first) // '🙂'
console.log(second) // '😔'5. The length property
const arr1 = [11, 21, 73]
const arr2 = new Array(7) // 7 empty slots
console.log(arr1.length) // 3
console.log(arr2.length) // 7
// Resize — adds empty slots or truncates
const arr = [11, 32]
arr.length = 5 // [11, 32, empty × 3]
arr.length = 0 // fastest way to empty (when writable)Edge cases:
arr2.length = 2 ** 32 // RangeError — max length 2³² − 1
new Array(-10) // RangeError — invalid length
// Non-writable length
const ages = [21, 12, 73, 41, 67]
Object.defineProperty(ages, 'length', { writable: false })
ages[5] = 6 // silently fails (strict: throws in some contexts)
ages.push(5) // TypeError — cannot change length6. Mutating methods
concat() — merge without mutating originals
const first = [1, 2, 3]
const second = [4, 5, 6]
const merged = first.concat(second)
console.log(merged) // [1, 2, 3, 4, 5, 6]
console.log(first) // [1, 2, 3] — unchangedjoin() — array to string
const emotions = ['🙂', '😍', '🙄', '😟']
emotions.join() // "🙂,😍,🙄,😟" — default comma
emotions.join('<=>') // "🙂<=>😍<=>🙄<=>😟"
;[].join() // ""fill() — mutates all or a range
const colors = ['red', 'blue', 'green']
colors.fill('pink') // ['pink', 'pink', 'pink']
const colors2 = ['red', 'blue', 'green']
colors2.fill('pink', 1, 3) // ['red', 'pink', 'pink']includes() & indexOf()
const names = ['tom', 'alex', 'bob', 'john']
names.includes('tom') // true
names.includes('july') // false
names.indexOf('alex') // 1
names.indexOf('rob') // -1
const dupes = ['tom', 'alex', 'bob', 'tom']
dupes.indexOf('tom') // 0 — first match
dupes.lastIndexOf('tom') // 3 — last matchreverse() & sort() — mutate in place
const names = ['tom', 'alex', 'bob']
names.reverse() // ['bob', 'alex', 'tom']
let artists = ['John White Abbott', 'Leonardo da Vinci', 'Charles Aubry', 'Anna Atkins', 'Barent Avercamp']
let sorted = artists.sort() // mutates AND returns same reference
console.log(artists === sorted) // true
// Descending compare function
artists.sort((a, b) => (a === b ? 0 : a > b ? -1 : 1))
// Numbers — default sort is lexicographic!
let ages = [2, 1000, 10, 3, 23, 12, 30, 21]
ages.sort() // [10, 1000, 12, 2, 21, 23, 3, 30] — wrong!
ages.sort((a, b) => a - b) // [2, 3, 10, 12, 21, 23, 30, 1000]splice() — insert, delete, or replace
const names = ['tom', 'alex', 'bob']
names.splice(1, 0, 'zack') // insert at index 1
// ['tom', 'zack', 'alex', 'bob']
const names2 = ['tom', 'alex', 'bob']
const deleted = names2.splice(2, 1, 'zack') // replace index 2
console.log(deleted) // ['bob']
console.log(names2) // ['tom', 'alex', 'zack']at() — negative index access
const junkFoodILove = ['🥖', '🍔', '🍟', '🍕', '🌭', '🥪', '🌮', '🍿']
junkFoodILove.at(0) // 🥖
junkFoodILove.at(3) // 🍕
junkFoodILove.at(-1) // 🍿
junkFoodILove.at(-5) // 🍕
junkFoodILove.at(10) // undefinedflat() — flatten nested arrays
const arr1 = [0, 1, 2, [3, 4]]
arr1.flat() // [0, 1, 2, 3, 4]
const arr2 = [0, 1, [2, [3, [4, 5]]]]
arr2.flat() // [0, 1, 2, [3, [4, 5]]]
arr2.flat(2) // deeper flatten
arr2.flat(Infinity) // fully flatcopyWithin() — copy segment in place
const array = [1, 2, 3, 4, 5, 6, 7]
array.copyWithin(0, 3, 6) // copy indices 3–5 to start
// [4, 5, 6, 4, 5, 6, 7]
const array2 = [1, 2, 3, 4, 5, 6, 7]
array2.copyWithin(0, 4)7. ES2023 immutable methods
// toSorted — non-mutating sort
const months = ['Mar', 'Jan', 'Feb', 'Dec']
const sortedMonths = months.toSorted()
console.log(sortedMonths) // ['Dec', 'Feb', 'Jan', 'Mar']
console.log(months) // unchanged
// toReversed
const items = [1, 2, 3]
const reversedItems = items.toReversed() // [3, 2, 1]
console.log(items) // [1, 2, 3] — unchanged
// toSpliced
const months2 = ['Jan', 'Mar', 'Apr', 'May']
const withFeb = months2.toSpliced(1, 0, 'Feb')
// with — replace at index (supports negative index)
const numbers = [1, 2, 3, 4, 5]
const newArray = numbers.with(2, 6)
console.log(numbers) // [1, 2, 3, 4, 5] — unchanged
console.log(newArray) // [1, 2, 6, 4, 5]
const anotherArray = numbers.with(-2, 8)
anotherArray.at(-2) // 88. Static methods & array-like objects
Array.of() vs new Array()
const a = new Array(2, 3, 4) // [2, 3, 4]
const b = [4, 5, 6]
const c = Array.of(2, false, 'test', { name: 'Alex' })
// Array.of(7) → [7] vs new Array(7) → 7 empty slotsArray-like objects
const arrayLike = {
0: 'A',
1: 'B',
2: 'C',
length: 3,
}
arrayLike[1] // 'B'
Array.from(arrayLike) // ['A', 'B', 'C']
// Other array-likes: NodeList, arguments
document.getElementsByTagName('li')
function checkArgs() {
console.log(arguments.length)
}Array.from()
const collection = Array.from(document.getElementsByTagName('li'))
// With map function
Array.from({ length: 5 }, (_, i) => i + 1) // [1, 2, 3, 4, 5]
Array.from('Hello') // ['H', 'e', 'l', 'l', 'o']Array.fromAsync()
Array.fromAsync({
length: 3,
0: Promise.resolve(''),
1: Promise.resolve('Google'),
2: Promise.resolve('Apple'),
}).then((array) => console.log(array))
// ['', 'Google', 'Apple']9. Iterator methods (HOFs)
Sample dataset used throughout:
const customers = [
{
id: 1,
f_name: 'Abby',
l_name: 'Thomas',
gender: 'M',
married: true,
age: 32,
expense: 500,
purchased: ['Shampoo', 'Toys', 'Book'],
},
{
id: 2,
f_name: 'Jerry',
l_name: 'Tom',
gender: 'M',
married: true,
age: 64,
expense: 100,
purchased: ['Stick', 'Blade'],
},
{
id: 3,
f_name: 'Dianna',
l_name: 'Cherry',
gender: 'F',
married: true,
age: 22,
expense: 1500,
purchased: ['Lipstik', 'Nail Polish', 'Bag', 'Book'],
},
{
id: 4,
f_name: 'Dev',
l_name: 'Currian',
gender: 'M',
married: true,
age: 82,
expense: 90,
purchased: ['Book'],
},
{
id: 5,
f_name: 'Maria',
l_name: 'Gomes',
gender: 'F',
married: false,
age: 7,
expense: 300,
purchased: ['Toys'],
},
]filter() — subset by condition
const seniorCustomers = customers.filter((customer) => customer.age >= 60)
console.log('[filter] Senior Customers =', seniorCustomers)map() — transform each element
const customersWithFullName = customers.map((customer) => {
let title = ''
if (customer.gender === 'M') title = 'Mr.'
else if (customer.gender === 'F' && customer.married) title = 'Mrs.'
else title = 'Miss'
return {
...customer,
full_name: `${title} ${customer.f_name} ${customer.l_name}`,
}
})
console.log('[map] Customers With Full Name =', customersWithFullName)reduce() — fold to one value
// Average age of customers who purchased 'Book'
let count = 0
const total = customers.reduce((accumulator, customer) => {
if (customer.purchased.includes('Book')) {
accumulator += customer.age
count += 1
}
return accumulator
}, 0)
console.log('[reduce] Customer Avg age Purchased Book:', Math.floor(total / count))some() / every() — boolean tests
const hasYoungCustomer = customers.some((customer) => customer.age < 10)
console.log('[some] Has Young Customer (Age < 10):', hasYoungCustomer)
const isThereWindowShopper = customers.every((customer) => customer.purchased.length === 0)
console.log('[every] Everyone a window shopper?', isThereWindowShopper)find() / findIndex() / findLast() / findLastIndex()
const foundYoungCustomer = customers.find((customer) => customer.age < 10)
console.log('[find] Found Young Customer:', foundYoungCustomer)
const index = customers.findIndex((customer) => customer.age < 10)
const lastFoundYoungCustomer = customers.findLast((customer) => customer.age < 10)
console.log('[findLast] Last Found Young Customer:', lastFoundYoungCustomer)
const lastIndex = customers.findLastIndex((customer) => customer.age < 10)entries() / values() — iterators
const numbers = [10, 20, 30]
for (const [index, value] of numbers.entries()) {
console.log(index, value)
}
for (const value of numbers.values()) {
console.log(value)
}flatMap() — map then flatten one level
const arr1 = [1, 2, 3, 4]
arr1.map((item) => item * 2) // [2, 4, 6, 8]
arr1.flatMap((item) => item * 2) // same for flat scalars
arr1.map((item) => [item * 2]) // [[2], [4], [6], [8]]
arr1.flatMap((item) => [item * 2]) // [2, 4, 6, 8] — flattened
arr1.map((item) => [[item * 2]]) // nested
arr1.flatMap((item) => [[item * 2]]) // [[2], [4], [6], [8]] — one level flatreduceRight() — fold right to left
const number = [100, 40, 15]
number.reduceRight((accumulator, current) => accumulator - current)
// 15 - 40 - 100 = -12510. Method chaining
Build a pipeline instead of intermediate variables:
// Step-by-step
const marriedCustomers = customers.filter((customer) => customer.married)
const expenseMapped = marriedCustomers.map((c) => c.expense)
const totalExpenseMarriedCustomer = expenseMapped.reduce((accum, expense) => accum + expense, 0)
console.log('Total Expense of Married Customers in INR:', totalExpenseMarriedCustomer)
// Chained — same result, cleaner
const total = customers
.filter((customer) => customer.married)
.map((married) => married.expense)
.reduce((accum, expense) => accum + expense, 0)
console.log('Orchestrated total expense in INR:', total)Mutating vs non-mutating — quick reference
| Mutates original | Returns new array |
|---|---|
push, pop, shift, unshift | map, filter, slice, concat |
splice, sort, reverse, fill | toSorted, toReversed, toSpliced, with |
copyWithin | flat, flatMap, spread [...arr] |
Practice Problems
Quick index
1. Fundamentals (T-001 – T-020)
2. Employee dataset (T-021 – T-048)
3. Array-like & static methods (T-049 – T-054)
1. Fundamentals (T-001 – T-020)
T-001: Create an array of 5 elements using the Array constructor
Answer:
const arr = new Array('apple', 'banana', 'cherry', 'date', 'elderberry')
console.log(arr.length) // 5T-002: Create an array of 3 empty slots
Answer:
const arr = new Array(3)
console.log(arr.length) // 3
console.log(0 in arr) // false — slot is empty, not undefinedT-003: Access the fourth element using length
Answer:
const arr = [10, 20, 30, 40, 50, 60]
const fourth = arr[arr.length - 3] // index 3 → 40
console.log(fourth) // 40T-004: Print elements at odd indices
Answer:
const arr = [10, 20, 30, 40, 50, 60]
for (let i = 0; i < arr.length; i++) {
if (i % 2 !== 0) {
console.log(arr[i]) // 20, 40, 60
}
}T-005: Add one element at the front and the end
Answer:
const arr = ['b', 'c']
arr.unshift('a') // front
arr.push('d') // end
console.log(arr) // ['a', 'b', 'c', 'd']T-006: Remove an element from the front and the end
Answer:
const arr = ['a', 'b', 'c', 'd']
arr.shift() // removes 'a'
arr.pop() // removes 'd'
console.log(arr) // ['b', 'c']T-007: Destructure the 6th food element
Answer:
const foods = ['pizza', 'pasta', 'burger', 'sushi', 'tacos', 'ramen', 'curry', 'salad', 'steak', 'dosa']
const [, , , , , sixthFood] = foods
console.log(sixthFood) // 'ramen'T-008: Take out the last 8 items using rest
Answer:
const foods = ['pizza', 'pasta', 'burger', 'sushi', 'tacos', 'ramen', 'curry', 'salad', 'steak', 'dosa']
const [first, second, ...lastEight] = foods
console.log(lastEight)
// ['burger', 'sushi', 'tacos', 'ramen', 'curry', 'salad', 'steak', 'dosa']T-009: Shallow clone an array
Answer:
const original = [1, 2, 3, 4]
const clone = [...original]
// or: original.slice()
// or: Array.from(original)
console.log(clone) // [1, 2, 3, 4]
console.log(clone === original) // falseT-010: Empty an array using length
Answer:
const arr = [1, 2, 3, 4, 5]
arr.length = 0
console.log(arr) // []T-011: Resize to length 6 when you find 5
Answer:
const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
for (let i = 0; i < arr.length; i++) {
if (arr[i] === 5) {
arr.length = 6
break
}
}
console.log(arr) // [1, 2, 3, 4, 5, 6]T-012: Empty an array with splice()
Answer:
const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
arr.splice(0)
console.log(arr) // []T-013: Most efficient way to empty an array?
Answer:
| Method | Notes |
|---|---|
length = 0 | Fastest — O(1), keeps same reference |
splice(0) | Works but slower for large arrays |
pop() / shift() in loop | O(n) — shifts remaining elements each time |
arr = [] | Only reassigns the variable, not the original reference others may hold |
const arr = [1, 2, 3, 4, 5]
arr.length = 0 // preferredT-014: Concatenate two empty arrays
Answer:
const result = [].concat([])
console.log(result) // []
console.log(result.length) // 0T-015: Check partial match against any element
Answer:
const words = ['javascript', 'typescript', 'python']
const query = 'script'
const hasPartialMatch = words.some((word) => word.includes(query))
console.log(hasPartialMatch) // true — 'javascript' contains 'script'T-016: slice() vs splice()
Answer:
slice(start, end) | splice(start, deleteCount, ...items) | |
|---|---|---|
| Mutates? | No | Yes |
| Returns | New sub-array | Array of removed items |
| Use | Copy a portion | Insert / delete / replace in place |
const arr = [1, 2, 3, 4, 5]
const copy = arr.slice(1, 3) // [2, 3] — arr unchanged
const removed = arr.splice(1, 2, 'a', 'b') // removes [2,3], inserts 'a','b'
// arr is now [1, 'a', 'b', 4, 5]T-017: Sort immutably (ascending & descending)
Answer:
const codes = ['b2', 'a10', 'a2', 'b1']
const ascending = codes.toSorted((a, b) => a.localeCompare(b, undefined, { numeric: true }))
const descending = codes.toSorted((a, b) => b.localeCompare(a, undefined, { numeric: true }))
console.log(ascending) // ['a2', 'a10', 'b1', 'b2']
console.log(descending) // ['b2', 'b1', 'a10', 'a2']
console.log(codes) // unchanged — ['b2', 'a10', 'a2', 'b1']T-018: Sparse vs dense arrays
Answer:
// Dense
const dense = [1, 2, 3, 4, 5]
// Sparse
const sparse = [1, , 3] // hole at index 1
const sparse2 = new Array(5) // 5 empty slots
console.log(1 in sparse) // false
console.log(sparse.length) // 3T-019: Practical uses of .fill()
Answer:
// Initialize a score board with zeros
const scores = new Array(5).fill(0) // [0, 0, 0, 0, 0]
// Reset only part of an array
const buffer = [1, 2, 3, 4, 5]
buffer.fill(-1, 2, 4) // [1, 2, -1, -1, 5]
// Create a 3×3 grid (same reference — use map for unique inner arrays)
const grid = Array.from({ length: 3 }, () => new Array(3).fill(0))T-020: Convert an array to a string
Answer:
const arr = ['hello', 'world']
arr.join() // "hello,world"
arr.join(' ') // "hello world"
arr.join(' - ') // "hello - world"
arr.toString() // "hello,world"
String(arr) // "hello,world"2. Employee dataset (T-021 – T-048)
Shared setup for all employee tasks:
const employees = [
{ id: 1, name: 'Alice', departmentId: 1, salary: 5000 },
{ id: 2, name: 'Bob', departmentId: 2, salary: 7000 },
{ id: 3, name: 'Charlie', departmentId: 3, salary: 4500 },
{ id: 4, name: 'Diana', departmentId: 1, salary: 5500 },
{ id: 5, name: 'Edward', departmentId: 2, salary: 8000 },
{ id: 6, name: 'Fiona', departmentId: 4, salary: 6000 },
{ id: 7, name: 'George', departmentId: 3, salary: 5200 },
{ id: 8, name: 'Helen', departmentId: 4, salary: 7200 },
{ id: 9, name: 'Ian', departmentId: 2, salary: 4800 },
{ id: 10, name: 'Jane', departmentId: 1, salary: 5100 },
]
const departments = [
{ id: 1, name: 'HR' },
{ id: 2, name: 'Engineering' },
{ id: 3, name: 'Marketing' },
{ id: 4, name: 'Sales' },
]
const getDeptName = (departmentId) => departments.find((d) => d.id === departmentId)?.name ?? 'Unknown'
const getDeptIdByName = (name) => departments.find((d) => d.name === name)?.idT-021: Filter employees in "Engineering"
Answer:
const engineeringId = getDeptIdByName('Engineering') // 2
const engineeringEmployees = employees.filter((emp) => emp.departmentId === engineeringId)
// Bob, Edward, IanT-022: Combine name and department — "Alice (HR)"
Answer:
const formatted = employees.map((emp) => `${emp.name} (${getDeptName(emp.departmentId)})`)
// ['Alice (HR)', 'Bob (Engineering)', ...]T-023: Highest salary
Answer:
const highestSalary = employees.reduce((max, emp) => (emp.salary > max ? emp.salary : max), 0)
// 8000
// Alternative
const highest = Math.max(...employees.map((e) => e.salary))T-024: At least one employee in "Sales"?
Answer:
const salesId = getDeptIdByName('Sales')
const hasSalesEmployee = employees.some((emp) => emp.departmentId === salesId)
// true — Fiona, HelenT-025: Function to filter by salary threshold
Answer:
function filterByMinSalary(minSalary) {
return employees.filter((emp) => emp.salary > minSalary)
}
const above6000 = filterByMinSalary(6000)
// Bob, Edward, Fiona, HelenT-026: Array of names only
Answer:
const names = employees.map((emp) => emp.name)
// ['Alice', 'Bob', 'Charlie', ...]T-027: Total salary with reduce
Answer:
const totalSalary = employees.reduce((sum, emp) => sum + emp.salary, 0)
// 58400T-028: Any employee earning less than 5000?
Answer:
const hasLowEarner = employees.some((emp) => emp.salary < 5000)
// true — Charlie (4500), Ian (4800)T-029: First employee earning exactly 5100
Answer:
const employee = employees.find((emp) => emp.salary === 5100)
// { id: 10, name: 'Jane', ... }T-030: Last employee in "HR"
Answer:
const hrId = getDeptIdByName('HR')
const lastInHR = employees.findLast((emp) => emp.departmentId === hrId)
// Jane (id: 10)T-031: First employee in "Marketing"
Answer:
const marketingId = getDeptIdByName('Marketing')
const firstInMarketing = employees.find((emp) => emp.departmentId === marketingId)
// Charlie (id: 3)T-032: All employees earn more than 4000?
Answer:
const allAbove4000 = employees.every((emp) => emp.salary > 4000)
// trueT-033: First employee in "Sales"
Answer:
const salesId = getDeptIdByName('Sales')
const firstInSales = employees.find((emp) => emp.departmentId === salesId)
// Fiona (id: 6)T-034: All employees belong to a listed department?
Answer:
const validDeptIds = new Set(departments.map((d) => d.id))
const allValid = employees.every((emp) => validDeptIds.has(emp.departmentId))
// trueT-035: Log each name and department
Answer:
employees.forEach((emp) => {
console.log(`${emp.name} — ${getDeptName(emp.departmentId)}`)
})T-036: Extract all names into one array
Answer:
const allNames = employees.map((emp) => emp.name)T-037: Increment each salary by 10%
Answer:
const withRaise = employees.map((emp) => ({
...emp,
salary: emp.salary * 1.1,
}))T-038: Flatten employee skills
Answer:
const employeesWithSkills = [
{ name: 'Alice', skills: ['Excel', 'Management'] },
{ name: 'Bob', skills: ['JavaScript', 'React'] },
{ name: 'Charlie', skills: ['SEO', 'Analytics'] },
]
const allSkills = employeesWithSkills.flatMap((emp) => emp.skills)
// ['Excel', 'Management', 'JavaScript', 'React', 'SEO', 'Analytics']T-039: Total salary in "Engineering"
Answer:
const engineeringId = getDeptIdByName('Engineering')
const engineeringTotal = employees
.filter((emp) => emp.departmentId === engineeringId)
.reduce((sum, emp) => sum + emp.salary, 0)
// 19800 (Bob 7000 + Edward 8000 + Ian 4800)T-040: Any department where all employees earn > 5000?
Answer:
const deptGroups = Object.groupBy(employees, (e) => e.departmentId)
const hasDeptAllAbove5000 = Object.values(deptGroups).some(
(group) => group.length > 0 && group.every((emp) => emp.salary > 5000),
)
// true — Engineering (all > 5000), Sales (6000, 7200)T-041: Count unique projects across employees
Answer:
const employeesWithProjects = [
{ id: 1, name: 'Alice', projects: ['Project A', 'Project B'] },
{ id: 2, name: 'Bob', projects: ['Project B', 'Project C'] },
{ id: 3, name: 'Charlie', projects: ['Project A'] },
]
const uniqueProjectCount = new Set(employeesWithProjects.flatMap((emp) => emp.projects)).size
// 3 — A, B, CT-042: Array of { name, departmentName }
Answer:
const withDept = employees.map((emp) => ({
name: emp.name,
departmentName: getDeptName(emp.departmentId),
}))T-043: Names of employees earning > 6000
Answer:
const highEarners = employees.filter((emp) => emp.salary > 6000).map((emp) => emp.name)
// ['Bob', 'Edward', 'Helen']T-044: for...of — print all names
Answer:
for (const emp of employees) {
console.log(emp.name)
}T-045: for...of — names earning > 5000
Answer:
for (const emp of employees) {
if (emp.salary > 5000) {
console.log(emp.name)
}
}T-046: Destructure in for...of — log name and salary
Answer:
for (const { name, salary } of employees) {
console.log(name, salary)
}T-047: Match employees with departments in for...of
Answer:
for (const emp of employees) {
const dept = departments.find((d) => d.id === emp.departmentId)
console.log(`${emp.name} works in ${dept?.name ?? 'Unknown'}`)
}T-048: entries() with for...of — index and name
Answer:
for (const [index, emp] of employees.entries()) {
console.log(index, emp.name)
}3. Array-like & static methods (T-049 – T-054)
T-049: Access second element of array-like object
Answer:
const arrayLike = { 0: 'First', 1: 'Second', length: 2 }
console.log(arrayLike[1]) // 'Second'T-050: Convert arguments to a real array
Answer:
function collectArgs() {
const argsArray = Array.from(arguments)
console.log(Array.isArray(argsArray)) // true
return argsArray
}
collectArgs(1, 2, 3) // [1, 2, 3]
// Modern alternative — prefer rest parameters
function collectArgsModern(...args) {
return args
}T-051: Convert NodeList from querySelectorAll to array
Answer:
const divs = document.querySelectorAll('div')
const divsArray = Array.from(divs)
// or: const divsArray = [...divs];
divsArray.forEach((div) => div.classList.add('highlight'))T-052: Merge two arrays
Answer:
const arr1 = [1, 2]
const arr2 = [3, 4]
const merged = [...arr1, ...arr2] // [1, 2, 3, 4]
// or: arr1.concat(arr2) // [1, 2, 3, 4]T-053: Five "A" values with Array.from
Answer:
const fiveAs = Array.from({ length: 5 }, () => 'A')
console.log(fiveAs) // ['A', 'A', 'A', 'A', 'A']T-054: Convert "Hello" to character array
Answer:
const chars = Array.from('Hello')
console.log(chars) // ['H', 'e', 'l', 'l', 'o']Quick reference — method by task
| Tasks | Primary methods |
|---|---|
| T-001 – T-006 | new Array(), literals, push, unshift, pop, shift |
| T-007 – T-009 | Destructuring, rest, spread, slice |
| T-010 – T-013 | length, splice, efficiency |
| T-014 – T-020 | concat, some, includes, slice vs splice, toSorted, fill, join |
| T-021 – T-048 | filter, map, reduce, some, every, find, findLast, flatMap, for...of |
| T-049 – T-054 | Array.from, spread, querySelectorAll |
Interview tip: After studying these answers, close the file and explain T-021, T-027, and T-040 aloud — they cover filter, reduce, and grouped logic interviewers love.
Subscribe to my newsletter
Stay up to date and get notified when I share new contents.
No spam ever, unsubscribe anytime