π¨ JavaScript Β· Topic 9 of 20
Array Methods β JavaScript Questions with Answers
30 practice questions on Array Methods, each with the correct answer and a clear explanation of why it is right. Read through them as revision notes, or take this topic as an interactive quiz to test yourself.
2 easy Β· 17 medium Β· 11 hard Β· Part of JavaScript: The language of the web - basics to advanced, 20 topics.
Medium questions (17)
Q3. medium
What is the key difference between map() and forEach()?
const doubled = nums.map(n => n * 2); // use the result
nums.forEach(n => console.log(n)); // side effect only
- A map RETURNS a new array; forEach returns undefined and is used for side effects
- B They are identical
- C forEach is faster and returns an array
- D map cannot use arrow functions
Answer: A β map RETURNS a new array; forEach returns undefined and is used for side effects
Use map when you want a transformed array back; use forEach when you just want to DO something per element (logging, DOM updates). Using map without using its result is a code smell.
mapforEach
Q4. medium
What does reduce() do?
const total = [1, 2, 3].reduce((sum, n) => sum + n, 0);
console.log(total); // 6
- A Boils an array down to a SINGLE value using an accumulator
- B Removes elements
- C Shrinks the array length
- D Sorts the array
Answer: A β Boils an array down to a SINGLE value using an accumulator
reduce((acc, item) => ..., initialValue) carries a running result across the array - sums, counts, groupings, even building objects.
reduceAccumulator
Q6. medium
What does find() return?
const users = [{id:1},{id:2}];
console.log(users.find(u => u.id === 2)); // {id: 2}
console.log(users.findIndex(u => u.id === 2)); // 1
- A The FIRST element matching the test, or undefined
- B All matching elements
- C The index of the match
- D true or false
Answer: A β The FIRST element matching the test, or undefined
find returns the element itself and stops at the first match. findIndex returns its position instead (or -1).
findfindIndex
Q7. medium
What is the difference between find() and filter()?
- A find returns ONE element (or undefined); filter returns an ARRAY of all matches
- B They are the same
- C find returns an array
- D filter stops at the first match
Answer: A β find returns ONE element (or undefined); filter returns an ARRAY of all matches
Use find when you expect a single result (it also stops early, so it is faster). filter always scans the whole array.
findfilter
Q8. medium
What do some() and every() return?
const n = [2, 4, 6];
console.log(n.some(x => x > 5)); // true
console.log(n.every(x => x % 2 === 0)); // true
console.log([].every(x => false)); // true!
- A Booleans - some: does AT LEAST ONE pass? every: do ALL pass?
- B Arrays of matches
- C The matching elements
- D Counts
Answer: A β Booleans - some: does AT LEAST ONE pass? every: do ALL pass?
Both short-circuit: some stops at the first true, every stops at the first false. Note every() on an EMPTY array is true (vacuous truth).
someevery
Q9. medium
What is the output?
console.log([1, 2, 3].map(n => n * 2).filter(n => n > 2));
- A [4, 6] - map first gives [2,4,6], then filter keeps > 2
- B [2, 4, 6]
- C [4]
- D [2, 3]
Answer: A β [4, 6] - map first gives [2,4,6], then filter keeps > 2
Array methods return arrays, so they CHAIN left to right. Each step creates a new array - readable, though it iterates more than once.
Chainingmapfilter
Q12. medium
What arguments does the map callback receive?
["a","b"].map((val, i) => `${i}: ${val}`);
// ["0: a", "1: b"]
- A (element, index, wholeArray)
- B (index, element)
- C Only the element
- D (array, index)
Answer: A β (element, index, wholeArray)
All iteration methods pass (value, index, array). You may ignore the extras - most callbacks only use the value.
CallbacksParameters
Q14. medium
How do you sum an array of objects' prices?
const cart = [{price: 100}, {price: 250}];
const total = cart.reduce((s, i) => s + i.price, 0); // 350
- A items.reduce((sum, item) => sum + item.price, 0)
- B items.sum("price")
- C items.map(i => i.price).total()
- D items.add(price)
Answer: A β items.reduce((sum, item) => sum + item.price, 0)
reduce with an accumulator starting at 0 is the standard total. Alternatively items.map(i => i.price).reduce((a,b) => a+b, 0).
reduceReal-world
Q16. medium
What does flatMap() do?
console.log(["a b", "c"].flatMap(s => s.split(" ")));
// ["a", "b", "c"]
- A Maps each element then flattens the result one level
- B Flattens only
- C Maps twice
- D Sorts and maps
Answer: A β Maps each element then flattens the result one level
flatMap is map + flat(1) in one pass - ideal when each input produces zero, one or many outputs.
flatMapflat
Q17. medium
How do you sort numbers ascending?
[10, 9, 100].sort((a, b) => a - b); // [9, 10, 100]
[10, 9, 100].sort((a, b) => b - a); // [100, 10, 9]
- A arr.sort((a, b) => a - b)
- B arr.sort()
- C arr.sort("asc")
- D arr.sortNumbers()
Answer: A β arr.sort((a, b) => a - b)
A comparator returning a negative number means 'a first', positive means 'b first', 0 means equal. a - b gives ascending; b - a gives descending.
sortComparator
Q18. medium
How do you sort an array of objects by a property?
users.sort((a, b) => a.age - b.age);
users.sort((a, b) => a.name.localeCompare(b.name));
- A arr.sort((a, b) => a.age - b.age) for numbers, or localeCompare for strings
- B arr.sort("age")
- C arr.sortBy(age)
- D arr.order(age)
Answer: A β arr.sort((a, b) => a.age - b.age) for numbers, or localeCompare for strings
Subtract for numeric fields; use a.name.localeCompare(b.name) for text so that accents and locale rules are handled correctly.
sortlocaleCompare
Q20. medium
Which methods do NOT mutate the original array?
- A map, filter, slice, concat, reduce, join
- B push, pop, splice, sort
- C All array methods mutate
- D No array methods mutate
Answer: A β map, filter, slice, concat, reduce, join
The functional methods return new values. The mutators are push, pop, shift, unshift, splice, sort, reverse and fill. Knowing which is which prevents surprise bugs.
ImmutabilityMutation
Q21. medium
What is the output?
console.log([1, 2, 3].includes(2), [1, 2, 3].indexOf(2));
console.log([NaN].includes(NaN)); // true
console.log([NaN].indexOf(NaN)); // -1
- A true 1
- B 1 true
- C true true
- D 2 2
Answer: A β true 1
includes gives a boolean; indexOf gives the position. includes also finds NaN correctly, which indexOf cannot.
includesindexOfNaN
Q23. medium
What does Array.from() do?
Array.from("abc"); // ["a","b","c"]
Array.from({length: 3}, (_, i) => i); // [0, 1, 2]
Array.from(document.querySelectorAll("p"));
- A Creates an array from an iterable or array-like object, optionally mapping each item
- B Copies only arrays
- C Sorts an array
- D Converts an array to a string
Answer: A β Creates an array from an iterable or array-like object, optionally mapping each item
Array.from turns strings, Sets, Maps, NodeLists and {length: n} objects into real arrays, with an optional map function as the second argument.
Array.fromArray-like
Q26. medium
How do you find the maximum value in an array?
console.log(Math.max(...[3, 7, 2])); // 7
console.log([3,7,2].reduce((m, x) => x > m ? x : m)); // 7
- A Math.max(...arr)
- B arr.max()
- C Math.max(arr)
- D arr.sort()[0]
Answer: A β Math.max(...arr)
Math.max takes separate arguments, so spread the array. Math.max(arr) would give NaN. For very large arrays use reduce to avoid argument limits.
Math.maxSpread
Q28. medium
What is the output?
const users = [{name:"Ana", age:30}, {name:"Ben", age:20}];
console.log(users.map(u => u.name).join(", "));
- A "Ana, Ben"
- B ["Ana","Ben"]
- C "AnaBen"
- D Error
Answer: A β "Ana, Ben"
map extracts the names into an array, then join turns them into a readable string. Extract-then-join is an everyday pattern for displaying lists.
mapjoinReal-world
Q30. medium
Which method would you use to check if EVERY form field is filled?
- A fields.every(f => f.value.trim() !== "")
- B fields.some(...)
- C fields.filter(...)
- D fields.map(...)
Answer: A β fields.every(f => f.value.trim() !== "")
every returns true only when all elements pass - exactly 'is the whole form valid?'. some would answer 'is at least one filled?'.
everyValidation
Hard questions (11)
Q5. hard
Why should you pass an initial value to reduce()?
arr.reduce(fn, 0)
[].reduce((a, b) => a + b); // TypeError!
[].reduce((a, b) => a + b, 0); // 0 - safe
- A Without it, reduce throws a TypeError on an EMPTY array and starts with element 0 otherwise
- B It is purely decorative
- C It makes reduce faster
- D It reverses the array
Answer: A β Without it, reduce throws a TypeError on an EMPTY array and starts with element 0 otherwise
With no initial value, the first element becomes the accumulator and an empty array raises 'Reduce of empty array with no initial value'. Passing 0 (or {} or []) also makes the intended type explicit.
reduceEdge cases
Q10. hard
What is the output?
console.log([1, 2, 3].map(n => { n * 2; }));
n => n * 2 // implicit return
n => { return n * 2; } // explicit return
n => { n * 2; } // returns undefined!
- A [undefined, undefined, undefined] - the arrow body has braces but no return
- B [2, 4, 6]
- C [1, 2, 3]
- D SyntaxError
Answer: A β [undefined, undefined, undefined] - the arrow body has braces but no return
With curly braces you must write return explicitly. Concise bodies without braces return automatically: n => n * 2. A very common beginner bug.
Arrow functionsImplicit return
Q11. hard
How do you return an OBJECT from a concise arrow function?
const wrap = n => ({ value: n });
console.log([1,2].map(wrap)); // [{value:1},{value:2}]
- A Wrap it in parentheses: n => ({ value: n })
- B n => { value: n }
- C n => return { value: n }
- D It is impossible
Answer: A β Wrap it in parentheses: n => ({ value: n })
Without parentheses the braces are parsed as a function BODY, not an object literal (giving undefined). Parentheses tell JavaScript it is an expression.
Arrow functionsObject literals
Q13. hard
What is the output?
console.log(["1", "2", "3"].map(parseInt));
- A [1, NaN, NaN] - map passes the index as parseInt's radix argument
- B [1, 2, 3]
- C ["1", "2", "3"]
- D [NaN, NaN, NaN]
Answer: A β [1, NaN, NaN] - map passes the index as parseInt's radix argument
map calls parseInt(value, index): parseInt("1",0)=1, parseInt("2",1)=NaN (radix 1 is invalid), parseInt("3",2)=NaN (3 is not a binary digit). Fix by wrapping: map(s => parseInt(s, 10)) or map(Number).
- A famous interview question about accidental extra arguments.
parseIntCallbacksGotchas
Q15. hard
What does this reduce build?
arr.reduce((acc, x) => { acc[x] = (acc[x] || 0) + 1; return acc; }, {})
const votes = ["a", "b", "a"];
console.log(votes.reduce((acc, v) => {
acc[v] = (acc[v] || 0) + 1; return acc;
}, {})); // { a: 2, b: 1 }
- A A frequency count object: { value: howManyTimes }
- B A sum
- C A sorted array
- D A filtered array
Answer: A β A frequency count object: { value: howManyTimes }
Starting with an empty object, each element increments its own counter. Counting occurrences is one of reduce's most useful patterns.
reduceCountingGrouping
Q19. hard
What is the output?
const a = [3, 1, 2];
const b = a.sort();
b.push(9);
console.log(a);
- A [1, 2, 3, 9] - sort mutates AND returns the SAME array, so a and b are one array
- B [3, 1, 2]
- C [1, 2, 3]
- D [9]
Answer: A β [1, 2, 3, 9] - sort mutates AND returns the SAME array, so a and b are one array
sort() sorts in place and returns a reference to the same array - it does not copy. Use [...a].sort() or a.toSorted() when you need to keep the original.
sortMutationReferences
Q22. hard
How do you get unique values, sorted, from [3,1,3,2]?
- A [...new Set([3,1,3,2])].sort((a,b) => a-b)
- B [3,1,3,2].unique().sort()
- C [3,1,3,2].filter(unique)
- D Set([3,1,3,2]).sort()
Answer: A β [...new Set([3,1,3,2])].sort((a,b) => a-b)
Set removes duplicates, spread converts back to an array, then sort with a numeric comparator gives [1, 2, 3]. Note a Set itself has no sort method.
SetsortChaining
Q24. hard
What is the output?
console.log([1,2,3].reduce((a, b) => a + b));
- A 6 - without an initial value, the first element becomes the accumulator
- B TypeError
- C [1,2,3]
- D 0
Answer: A β 6 - without an initial value, the first element becomes the accumulator
Omitting the initial value starts with acc=1, b=2 (giving 3), then acc=3, b=3 (giving 6). It works for non-empty arrays, but always passing an initial value is safer.
reduceInitial value
Q25. hard
What does this do?
arr.filter(Boolean)
console.log([0, "a", null, "b", ""].filter(Boolean));
// ["a", "b"]
- A Removes all falsy values (0, "", null, undefined, NaN, false)
- B Converts everything to booleans
- C Keeps only booleans
- D Throws an error
Answer: A β Removes all falsy values (0, "", null, undefined, NaN, false)
Boolean is passed as the callback: each element is converted, and only truthy ones survive. A clean idiom for cleaning data.
filterTruthiness
Q27. hard
What is the performance concern with chaining many array methods?
arr.map(...).filter(...).map(...)
- A Each step creates a new array and iterates again - fine for small data, wasteful for very large arrays
- B It always crashes
- C Chaining is impossible
- D It mutates the original
Answer: A β Each step creates a new array and iterates again - fine for small data, wasteful for very large arrays
Three chained calls mean three passes and three temporary arrays. For typical UI data this is irrelevant and readability wins; for huge datasets a single reduce or for...of loop is more efficient.
PerformanceChaining
Q29. hard
How would you group items by a property using reduce?
const byType = items.reduce((acc, item) => {
(acc[item.type] ||= []).push(item);
return acc;
}, {});
- A reduce((acc, item) => { (acc[item.type] ||= []).push(item); return acc; }, {})
- B arr.groupBy("type")
- C arr.filter("type")
- D arr.sort("type")
Answer: A β reduce((acc, item) => { (acc[item.type] ||= []).push(item); return acc; }, {})
Create the array for a key if missing, then push. (Object.groupBy exists in very new environments, but the reduce pattern works everywhere.)
reduceGrouping