mediumJS ES5#59

Array.map manually

Prompt

Implement your own version of Array.prototype.map as a standalone function myMap(arr, callback). It must return a NEW array (never mutate the input) and pass (element, index, array) to the callback.

Solution

function myMap(arr, callback) {
  var result = []
  for (var i = 0; i < arr.length; i++) {
    result.push(callback(arr[i], i, arr))
  }
  return result
}
Mentor's take

Interviewers ask for map reimplementations because the exercise exposes whether you know the contract, not just the one-argument usage everyone types daily. Map exists to express "same-shape transformation" as a value-producing operation: input untouched, output a new array of identical length, one call per element. That immutability guarantee is why map-produced arrays are safe to hand to React state or memoized selectors — a new reference signals a change, and nobody upstream sees their data mutated.

The mechanics are a loop with three obligations. Fresh result array; push the callback's return value (whatever it is — undefined included, map never filters); and pass the full triple (element, index, array), because callers legitimately use the index and occasionally the whole array. Skipping the extra arguments is the most common "works on my test" bug — and it's also the source of the classic ['1','7','11'].map(parseInt) trap, where the index lands in parseInt's radix parameter. Knowing the triple is why you can explain that trap.

Honest scoping earns points: the real spec also skips holes in sparse arrays and accepts a thisArg — say you're deliberately omitting those, don't let the interviewer discover it.

Red flag: writing arr[i] = callback(arr[i]) and returning arr. In-place mutation breaks every caller who kept a reference to the input — it's the difference between a transformation and a side effect.

Say it: "Map is a pure same-length transformation — new array out, input untouched, callback receives element, index, and array, which is exactly why map(parseInt) misbehaves."