Kazi Rahamatullah
Kazi Rahamatullah
AboutProjectsBlogContact
UsesBooks
ResumeView CV
Kazi Rahamatullah

© Copyright 2026 Kazi Rahamatullah

AboutProjectsBlogBooksUses
Twitter/XGitHubProduct HuntCodeSandbox
Back to Blog
JavaScriptArraysInterview PreparationFrontend DevelopmentES6

JavaScript Arrays

Complete array guide for interviews — creation, destructuring, mutating vs non-mutating methods, higher-order functions, ES2023 immutability, and practice problems with solutions.

Jul 2, 202633 min read

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

#Section
1Creation & access
2Add, remove, clone
3Array.isArray
4Destructuring, rest & spread
5The length property
6Mutating methods
7ES2023 immutable methods
8Static methods & array-like objects
9Iterator methods (HOFs)
10Method chaining

1. Creation & access

Create an array

javascript
const salad = ['🍅', '🍄', '🥦', '🥒', '🌽', '🥕', '🥑']
const anotherSalad = new Array('🍅', '🍄', '🥦', '🥒', '🌽', '🥕', '🥑')

Interview Answer

Prefer array literals [] over new Array() unless you need Array.of() or Array.from(). new Array(7) creates an array with 7 empty slots (holes), not seven undefined values.

Get elements by index

javascript
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

javascript
const salad = ['🍅', '🍄', '🥦', '🥒', '🌽', '🥕', '🥑']
 
for (let i = 0; i < salad.length; i++) {
  console.log(`Element at index ${i} is ${salad[i]}`)
}

Back to index


2. Add, remove, clone

Add elements

javascript
const salad = ['🍅', '🍄', '🥦', '🥒', '🌽', '🥕', '🥑']
 
salad.push('🥜') // add at end — mutates
salad.unshift('🥜') // add at front — mutates

Remove elements

javascript
const salad = ['🍅', '🍄', '🥦', '🥒', '🌽', '🥕', '🥑']
salad.pop() // removes last — returns '🥑'
console.log(salad) // ['🍅', '🍄', '🥦', '🥒', '🌽', '🥕']

Shallow clone with slice()

javascript
const salad = ['🍅', '🍄', '🥦', '🥒', '🌽', '🥕', '🥑']
const saladCopy = salad.slice()
 
console.log(saladCopy) // same values
salad === saladCopy // false — different reference

Interview Answer

slice() with no args, spread [...arr], or Array.from(arr) all create a shallow copy. Nested objects are still shared.

Back to index


3. Array.isArray

javascript
Array.isArray(['🍅', '🍄', '🥦']) // true
Array.isArray('🍅') // false
Array.isArray({ tomato: '🍅' }) // false
Array.isArray([]) // true

Interview Answer

Always use Array.isArray() — not typeof (returns 'object') and not instanceof Array (breaks across iframes).

Back to index


4. Destructuring, rest & spread

Basic destructuring

javascript
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

javascript
let [tomato, mushroom = '🍄'] = ['🍅']
console.log(tomato) // '🍅'
console.log(mushroom) // '🍄' — default applied

Skip a value

javascript
let [tomato, , carrot] = ['🍅', '🍄', '🥕']
console.log(tomato) // '🍅'
console.log(carrot) // '🥕'

Nested destructuring

javascript
let fruits = ['🍈', '🍍', '🍌', '🍉', ['🍅', '🍄', '🥕']]
 
const veg = fruits[4] // ['🍅', '🍄', '🥕']
const carrot = veg[2] // '🥕'
fruits[4][2] // '🥕'
 
let [, , , , [, , carrot2]] = ['🍈', '🍍', '🍌', '🍉', ['🍅', '🍄', '🥕']]

Rest parameter

javascript
const [tomato, mushroom, ...rest] = ['🍅', '🍄', '🥦', '🥒', '🌽', '🥕', '🥑']
 
console.log(tomato) // '🍅'
console.log(mushroom) // '🍄'
console.log(rest) // ['🥦', '🥒', '🌽', '🥕', '🥑']

Spread operator — clone & merge

javascript
const salad = ['🍅', '🍄', '🥦', '🥒', '🌽', '🥕', '🥑']
const saladCloned = [...salad]
salad === saladCloned // false
 
// Merge arrays
const emotion = ['🙂', '😔']
const veggies = ['🥦', '🥒', '🌽', '🥕']
const emotionalVeggies = [...emotion, ...veggies]
// ['🙂', '😔', '🥦', '🥒', '🌽', '🥕']

Swap values

javascript
let first = '😔'
let second = '🙂'
;[first, second] = [second, first]
 
console.log(first) // '🙂'
console.log(second) // '😔'

Interview Answer

Rest collects remaining elements into an array; spread expands an iterable into elements. Both use ... syntax but opposite directions.

Back to index


5. The length property

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

javascript
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 length

Interview Answer

Setting length = 0 is the most efficient way to empty an array when length is writable. splice(0) also works but is slower for large arrays.

Back to index


6. Mutating methods

concat() — merge without mutating originals

javascript
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] — unchanged

join() — array to string

javascript
const emotions = ['🙂', '😍', '🙄', '😟']
 
emotions.join() // "🙂,😍,🙄,😟" — default comma
emotions.join('<=>') // "🙂<=>😍<=>🙄<=>😟"
;[].join() // ""

fill() — mutates all or a range

javascript
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()

javascript
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 match

reverse() & sort() — mutate in place

javascript
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

javascript
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

javascript
const junkFoodILove = ['🥖', '🍔', '🍟', '🍕', '🌭', '🥪', '🌮', '🍿']
 
junkFoodILove.at(0) // 🥖
junkFoodILove.at(3) // 🍕
junkFoodILove.at(-1) // 🍿
junkFoodILove.at(-5) // 🍕
junkFoodILove.at(10) // undefined

flat() — flatten nested arrays

javascript
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 flat

copyWithin() — copy segment in place

javascript
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)

Back to index


7. ES2023 immutable methods

javascript
// 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) // 8

Interview Answer

In React/Redux state, prefer toSorted(), toReversed(), toSpliced(), and with() over mutating sort/reverse/splice. Only the copy changes.

Back to index


8. Static methods & array-like objects

Array.of() vs new Array()

javascript
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 slots

Array-like objects

javascript
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()

javascript
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()

javascript
Array.fromAsync({
  length: 3,
  0: Promise.resolve(''),
  1: Promise.resolve('Google'),
  2: Promise.resolve('Apple'),
}).then((array) => console.log(array))
// ['', 'Google', 'Apple']

Interview Answer

Array.from converts any array-like or iterable to a real array. Only this method (or spread on iterables) — needed for NodeList and arguments.

Back to index


9. Iterator methods (HOFs)

Sample dataset used throughout:

javascript
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

javascript
const seniorCustomers = customers.filter((customer) => customer.age >= 60)
console.log('[filter] Senior Customers =', seniorCustomers)

map() — transform each element

javascript
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

javascript
// 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

javascript
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()

javascript
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

javascript
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

javascript
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 flat

reduceRight() — fold right to left

javascript
const number = [100, 40, 15]
 
number.reduceRight((accumulator, current) => accumulator - current)
// 15 - 40 - 100 = -125

Interview Answer

filter → subset, map → transform, reduce → single value. some/every short-circuit; find returns first match or undefined. Prefer flatMap over map().flat() when each callback returns an array.

Back to index


10. Method chaining

Build a pipeline instead of intermediate variables:

javascript
// 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)

Interview Answer

Method chaining works because each HOF returns an array (except reduce which terminates the chain). Keep pipelines readable — if a chain exceeds 3–4 steps, extract named steps or helper functions.

Back to index


Mutating vs non-mutating — quick reference

Mutates originalReturns new array
push, pop, shift, unshiftmap, filter, slice, concat
splice, sort, reverse, filltoSorted, toReversed, toSpliced, with
copyWithinflat, flatMap, spread [...arr]

Practice Problems

Quick index

1. Fundamentals (T-001 – T-020)

#Question
T-001: Create an array of 5 elements using the Array constructor
T-002: Create an array of 3 empty slots
T-003: Access the fourth element using length
T-004: Print elements at odd indices
T-005: Add one element at the front and the end
T-006: Remove an element from the front and the end
T-007: Destructure the 6th food element
T-008: Take out the last 8 items using rest
T-009: Shallow clone an array
T-010: Empty an array using length
T-011: Resize to length 6 when you find 5
T-012: Empty an array with splice()
T-013: Most efficient way to empty an array?
T-014: Concatenate two empty arrays
T-015: Check partial match against any element
T-016: slice() vs splice()
T-017: Sort immutably (ascending & descending)
T-018: Sparse vs dense arrays
T-019: Practical uses of .fill()
T-020: Convert an array to a string

2. Employee dataset (T-021 – T-048)

#Question
T-021: Filter employees in "Engineering"
T-022: Combine name and department — "Alice (HR)"
T-023: Highest salary
T-024: At least one employee in "Sales"?
T-025: Function to filter by salary threshold
T-026: Array of names only
T-027: Total salary with reduce
T-028: Any employee earning less than 5000?
T-029: First employee earning exactly 5100
T-030: Last employee in "HR"
T-031: First employee in "Marketing"
T-032: All employees earn more than 4000?
T-033: First employee in "Sales"
T-034: All employees belong to a listed department?
T-035: Log each name and department
T-036: Extract all names into one array
T-037: Increment each salary by 10%
T-038: Flatten employee skills
T-039: Total salary in "Engineering"
T-040: Any department where all employees earn > 5000?
T-041: Count unique projects across employees
T-042: Array of { name, departmentName }
T-043: Names of employees earning > 6000
T-044: for...of — print all names
T-045: for...of — names earning > 5000
T-046: Destructure in for...of — log name and salary
T-047: Match employees with departments in for...of
T-048: entries() with for...of — index and name

3. Array-like & static methods (T-049 – T-054)

#Question
T-049: Access second element of array-like object
T-050: Convert arguments to a real array
T-051: Convert NodeList from querySelectorAll to array
T-052: Merge two arrays
T-053: Five "A" values with Array.from
T-054: Convert "Hello" to character array

1. Fundamentals (T-001 – T-020)

T-001: Create an array of 5 elements using the Array constructor

Answer:

Warning

Pass five values to new Array(...). Each argument becomes an element. Do not confuse this with new Array(5), which creates five empty slots.

javascript
const arr = new Array('apple', 'banana', 'cherry', 'date', 'elderberry')
console.log(arr.length) // 5

Back to index


T-002: Create an array of 3 empty slots

Answer:

Note

When Array receives a single number, it creates a sparse array with that many empty slots (holes), not three undefined values.

javascript
const arr = new Array(3)
console.log(arr.length) // 3
console.log(0 in arr) // false — slot is empty, not undefined

Back to index


T-003: Access the fourth element using length

Answer:

Note

The fourth element sits at index length - 3 (1st → length - 4, 2nd → length - 3, …). Alternatively use index 3 directly.

javascript
const arr = [10, 20, 30, 40, 50, 60]
const fourth = arr[arr.length - 3] // index 3 → 40
console.log(fourth) // 40

Back to index


T-004: Print elements at odd indices

Answer:

Note

Odd indices are 1, 3, 5, … — check i % 2 !== 0 inside a for loop.

javascript
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
  }
}

Back to index


T-005: Add one element at the front and the end

Answer:

Note

unshift() adds to the front; push() adds to the end. Both mutate the original array.

javascript
const arr = ['b', 'c']
arr.unshift('a') // front
arr.push('d') // end
console.log(arr) // ['a', 'b', 'c', 'd']

Back to index


T-006: Remove an element from the front and the end

Answer:

Note

shift() removes from the front; pop() removes from the end. Both return the removed value.

javascript
const arr = ['a', 'b', 'c', 'd']
arr.shift() // removes 'a'
arr.pop() // removes 'd'
console.log(arr) // ['b', 'c']

Back to index


T-007: Destructure the 6th food element

Answer:

Note

Skip the first five positions with commas, then bind the sixth value. Index 5 = 6th element.

javascript
const foods = ['pizza', 'pasta', 'burger', 'sushi', 'tacos', 'ramen', 'curry', 'salad', 'steak', 'dosa']
const [, , , , , sixthFood] = foods
console.log(sixthFood) // 'ramen'

Back to index


T-008: Take out the last 8 items using rest

Answer:

Note

Destructure the first two items, then collect the rest into a new array with ...rest.

javascript
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']

Back to index


T-009: Shallow clone an array

Answer:

Note

Spread, slice(), and Array.from() all create a new array with the same top-level values. Nested objects are still shared (shallow copy).

javascript
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) // false

Back to index


T-010: Empty an array using length

Answer:

Performance

Setting length to 0 truncates the array in place — O(1) and very efficient.

javascript
const arr = [1, 2, 3, 4, 5]
arr.length = 0
console.log(arr) // []

Back to index


T-011: Resize to length 6 when you find 5

Answer:

Note

Loop through the array; when the value 5 is found, set length = 6 to truncate everything after index 5.

javascript
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]

Back to index


T-012: Empty an array with splice()

Answer:

Note

splice(0) removes all elements starting at index 0 and returns them. The array becomes empty.

javascript
const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
arr.splice(0)
console.log(arr) // []

Back to index


T-013: Most efficient way to empty an array?

Answer:

Performance

arr.length = 0 is the most efficient. It clears in place in O(1) time without creating a new array or shifting elements one by one.

MethodNotes
length = 0Fastest — O(1), keeps same reference
splice(0)Works but slower for large arrays
pop() / shift() in loopO(n) — shifts remaining elements each time
arr = []Only reassigns the variable, not the original reference others may hold
javascript
const arr = [1, 2, 3, 4, 5]
arr.length = 0 // preferred

Back to index


T-014: Concatenate two empty arrays

Answer:

Note

Returns a new empty array []. The result has length 0 and is a different reference from either input.

javascript
const result = [].concat([])
console.log(result) // []
console.log(result.length) // 0

Back to index


T-015: Check partial match against any element

Answer:

Note

Use some() with includes() on strings, or a custom predicate. includes() alone only checks full equality.

javascript
const words = ['javascript', 'typescript', 'python']
 
const query = 'script'
const hasPartialMatch = words.some((word) => word.includes(query))
console.log(hasPartialMatch) // true — 'javascript' contains 'script'

Back to index


T-016: slice() vs splice()

Answer:

slice(start, end)splice(start, deleteCount, ...items)
Mutates?NoYes
ReturnsNew sub-arrayArray of removed items
UseCopy a portionInsert / delete / replace in place
javascript
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]

Back to index


T-017: Sort immutably (ascending & descending)

Answer:

Warning

Use toSorted() (ES2023) or [...arr].sort() so the source array never changes.

javascript
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']

Back to index


T-018: Sparse vs dense arrays

Answer:

Warning

A dense array has a value at every index from 0 to length - 1. A sparse array has holes — missing indices that were never assigned.

javascript
// 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) // 3

Back to index


T-019: Practical uses of .fill()

Answer:

Note

Initialize arrays with a default value, reset buffers, or pad a range without a manual loop.

javascript
// 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))

Back to index


T-020: Convert an array to a string

Answer:

Note

join(separator) gives control over the delimiter. toString() joins with commas. String(arr) behaves like toString().

javascript
const arr = ['hello', 'world']
 
arr.join() // "hello,world"
arr.join(' ') // "hello world"
arr.join(' - ') // "hello - world"
arr.toString() // "hello,world"
String(arr) // "hello,world"

Back to index


2. Employee dataset (T-021 – T-048)

Shared setup for all employee tasks:

javascript
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)?.id

T-021: Filter employees in "Engineering"

Answer:

Note

Find the department id first, then filter employees by departmentId.

javascript
const engineeringId = getDeptIdByName('Engineering') // 2
 
const engineeringEmployees = employees.filter((emp) => emp.departmentId === engineeringId)
// Bob, Edward, Ian

Back to index


T-022: Combine name and department — "Alice (HR)"

Answer:

Note

map each employee to a formatted string using a department lookup.

javascript
const formatted = employees.map((emp) => `${emp.name} (${getDeptName(emp.departmentId)})`)
// ['Alice (HR)', 'Bob (Engineering)', ...]

Back to index


T-023: Highest salary

Answer:

Note

reduce to track the max, or Math.max with spread over mapped salaries.

javascript
const highestSalary = employees.reduce((max, emp) => (emp.salary > max ? emp.salary : max), 0)
// 8000
 
// Alternative
const highest = Math.max(...employees.map((e) => e.salary))

Back to index


T-024: At least one employee in "Sales"?

Answer:

Note

some() returns true as soon as one match is found.

javascript
const salesId = getDeptIdByName('Sales')
 
const hasSalesEmployee = employees.some((emp) => emp.departmentId === salesId)
// true — Fiona, Helen

Back to index


T-025: Function to filter by salary threshold

Answer:

Note

Accept a minimum salary parameter and return a reusable filter function or filtered array.

javascript
function filterByMinSalary(minSalary) {
  return employees.filter((emp) => emp.salary > minSalary)
}
 
const above6000 = filterByMinSalary(6000)
// Bob, Edward, Fiona, Helen

Back to index


T-026: Array of names only

Answer:

Note

map to extract the name property from each object.

javascript
const names = employees.map((emp) => emp.name)
// ['Alice', 'Bob', 'Charlie', ...]

Back to index


T-027: Total salary with reduce

Answer:

Note

Accumulate salaries starting from 0.

javascript
const totalSalary = employees.reduce((sum, emp) => sum + emp.salary, 0)
// 58400

Back to index


T-028: Any employee earning less than 5000?

Answer:

Note

some() short-circuits on the first match.

javascript
const hasLowEarner = employees.some((emp) => emp.salary < 5000)
// true — Charlie (4500), Ian (4800)

Back to index


T-029: First employee earning exactly 5100

Answer:

Note

find() returns the first matching object or undefined.

javascript
const employee = employees.find((emp) => emp.salary === 5100)
// { id: 10, name: 'Jane', ... }

Back to index


T-030: Last employee in "HR"

Answer:

Note

findLast() (ES2023) searches from the end. Filter + pop also works.

javascript
const hrId = getDeptIdByName('HR')
 
const lastInHR = employees.findLast((emp) => emp.departmentId === hrId)
// Jane (id: 10)

Back to index


T-031: First employee in "Marketing"

Answer:

Note

find() returns the first match from the start.

javascript
const marketingId = getDeptIdByName('Marketing')
 
const firstInMarketing = employees.find((emp) => emp.departmentId === marketingId)
// Charlie (id: 3)

Back to index


T-032: All employees earn more than 4000?

Answer:

Note

every() returns true only if all elements pass the test.

javascript
const allAbove4000 = employees.every((emp) => emp.salary > 4000)
// true

Back to index


T-033: First employee in "Sales"

Answer:

Note

Same pattern as T-031 with the Sales department id.

javascript
const salesId = getDeptIdByName('Sales')
 
const firstInSales = employees.find((emp) => emp.departmentId === salesId)
// Fiona (id: 6)

Back to index


T-034: All employees belong to a listed department?

Answer:

Note

Build a Set of valid department ids, then every() employee must have a matching id.

javascript
const validDeptIds = new Set(departments.map((d) => d.id))
 
const allValid = employees.every((emp) => validDeptIds.has(emp.departmentId))
// true

Back to index


T-035: Log each name and department

Answer:

Note

forEach for side effects — lookup department name per employee.

javascript
employees.forEach((emp) => {
  console.log(`${emp.name} — ${getDeptName(emp.departmentId)}`)
})

Back to index


T-036: Extract all names into one array

Answer:

Note

Identical to T-026 — map to pluck the name field.

javascript
const allNames = employees.map((emp) => emp.name)

Back to index


T-037: Increment each salary by 10%

Answer:

Warning

map to return new objects with updated salary — do not mutate originals if immutability matters.

javascript
const withRaise = employees.map((emp) => ({
  ...emp,
  salary: emp.salary * 1.1,
}))

Back to index


T-038: Flatten employee skills

Answer:

Note

flatMap maps each employee to their skills array and flattens one level.

javascript
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']

Back to index


T-039: Total salary in "Engineering"

Answer:

Note

Chain filter then reduce, or use a single reduce with a condition.

javascript
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)

Back to index


T-040: Any department where all employees earn > 5000?

Answer:

Note

Group employees by department, then check if every group has all salaries above 5000 and at least one member.

javascript
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)

Back to index


T-041: Count unique projects across employees

Answer:

Note

Collect all projects with flatMap, then deduplicate with Set.

javascript
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, C

Back to index


T-042: Array of { name, departmentName }

Answer:

Note

map each employee, resolve department name via lookup.

javascript
const withDept = employees.map((emp) => ({
  name: emp.name,
  departmentName: getDeptName(emp.departmentId),
}))

Back to index


T-043: Names of employees earning > 6000

Answer:

Note

filter then map — or chain in one expression.

javascript
const highEarners = employees.filter((emp) => emp.salary > 6000).map((emp) => emp.name)
// ['Bob', 'Edward', 'Helen']

Back to index


T-044: for...of — print all names

Answer:

Note

for...of iterates values directly — cleaner than index-based loops for arrays of objects.

javascript
for (const emp of employees) {
  console.log(emp.name)
}

Back to index


T-045: for...of — names earning > 5000

Answer:

Note

Add a condition inside the loop before logging.

javascript
for (const emp of employees) {
  if (emp.salary > 5000) {
    console.log(emp.name)
  }
}

Back to index


T-046: Destructure in for...of — log name and salary

Answer:

Note

Destructure { name, salary } directly in the loop header.

javascript
for (const { name, salary } of employees) {
  console.log(name, salary)
}

Back to index


T-047: Match employees with departments in for...of

Answer:

Note

Look up the department inside the loop and log the pairing.

javascript
for (const emp of employees) {
  const dept = departments.find((d) => d.id === emp.departmentId)
  console.log(`${emp.name} works in ${dept?.name ?? 'Unknown'}`)
}

Back to index


T-048: entries() with for...of — index and name

Answer:

Note

entries() yields [index, value] pairs ideal for destructuring in for...of.

javascript
for (const [index, emp] of employees.entries()) {
  console.log(index, emp.name)
}

Back to index


3. Array-like & static methods (T-049 – T-054)

T-049: Access second element of array-like object

Answer:

Note

Array-like objects use numeric keys and a length property. Access index 1 directly — or convert with Array.from first.

javascript
const arrayLike = { 0: 'First', 1: 'Second', length: 2 }
 
console.log(arrayLike[1]) // 'Second'

Back to index


T-050: Convert arguments to a real array

Answer:

Note

Array.from(arguments) (or rest parameters in modern code) produces a true array with all array methods.

javascript
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
}

Back to index


T-051: Convert NodeList from querySelectorAll to array

Answer:

Note

querySelectorAll returns a NodeList — array-like but not a full array. Spread or Array.from converts it.

javascript
const divs = document.querySelectorAll('div')
const divsArray = Array.from(divs)
// or: const divsArray = [...divs];
 
divsArray.forEach((div) => div.classList.add('highlight'))

Back to index


T-052: Merge two arrays

Answer:

Note

Spread is the most common approach. concat also works and does not mutate either source.

javascript
const arr1 = [1, 2]
const arr2 = [3, 4]
 
const merged = [...arr1, ...arr2] // [1, 2, 3, 4]
// or: arr1.concat(arr2)           // [1, 2, 3, 4]

Back to index


T-053: Five "A" values with Array.from

Answer:

Note

Pass { length: n } as array-like and a mapper function to fill each slot.

javascript
const fiveAs = Array.from({ length: 5 }, () => 'A')
console.log(fiveAs) // ['A', 'A', 'A', 'A', 'A']

Back to index


T-054: Convert "Hello" to character array

Answer:

Note

Strings are iterables — Array.from splits into Unicode code units (characters).

javascript
const chars = Array.from('Hello')
console.log(chars) // ['H', 'e', 'l', 'l', 'o']

Back to index


Quick reference — method by task

TasksPrimary methods
T-001 – T-006new Array(), literals, push, unshift, pop, shift
T-007 – T-009Destructuring, rest, spread, slice
T-010 – T-013length, splice, efficiency
T-014 – T-020concat, some, includes, slice vs splice, toSorted, fill, join
T-021 – T-048filter, map, reduce, some, every, find, findLast, flatMap, for...of
T-049 – T-054Array.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.

Share this article

XLinkedInFacebook
Kazi Rahamatullah

Written by

Kazi Rahamatullah

FullStack Developer

X / TwitterGitHubLinkedIn

Subscribe to my newsletter

Stay up to date and get notified when I share new contents.

No spam ever, unsubscribe anytime