EasyAmazonByteDanceApple

Polyfill: map()

Prompt

Imagine the JavaScript array method .map() does not exist. Implement a myMap method on Array.prototype that works like the native .map().

Playground

Hint 1

map is like forEach but it collects the return value of each callback call into a new array. Create an empty array, loop through this, push the callback result for each element, and return the new array.

Hint 2

The callback receives three arguments: callback(element, index, array). Use a regular for loop (not for...of) so you have access to the index.

Solution

Explanation

map is almost identical to forEach. The only difference is that map collects the return value of each callback into a new array and returns it.

// forEach: just calls the function, returns nothing
// map: calls the function, collects results into a new array

const result = [];

for (let i = 0; i < this.length; i++) {
result.push(callback(this[i], i, this));
}

return result;

For each element, we call the callback with (element, index, array) and push whatever it returns into result. At the end, we return result. The original array is never modified.

The returned array always has the same length as the original. If your callback doesn't explicitly return something, JavaScript returns undefined by default, so you'd get an array full of undefined values. That's not a bug in our polyfill, that's how the native .map() works too.

map vs forEach

If you're not using the returned array, you should use forEach instead of map. Using map just for side effects (like logging) is considered bad practice because you're creating an array that gets thrown away.

Why not for...of?

You might be tempted to use for (const element of this) since it's cleaner. But for...of only gives you the element, not the index. The native .map() passes (element, index, array) to the callback, so we need a regular for loop to have access to i.

When do you use map?

  • Data transformation: converting an array of objects into a different shape (e.g., extracting just the names from a list of users)
  • Rendering lists in React: items.map(item => <Item key={item.id} {...item} />)
  • Formatting data: converting numbers to strings, adding prefixes, changing date formats
  • Deriving new values: computing new values from existing ones without modifying the original