RxJS icon Launch Deal: Get $100 off the RxJS Kickstart Bundle now!

RxJS Masterclass is here. 2-course bundle - buy now (discount applied at checkout).

days
hours
mins
secs

Exploring Array Map in JavaScript

Mar 24, 2020 7 mins read

JavaScript post
JavaScript icon

Want to level up your JavaScript skills? Who doesn't. Here's what you need to know

Show Me View JavaScript courses

Welcome to the second article in this exploring array prototypes series where you will learn how to use the array prototype method - Map! In this article, you’ll learn how, when and why you should use Map that covers a lot of real-world tips and common pitfalls developers new to Map typically have.

Follow the Array Prototype Series!

You can also follow along with the rest of this series of posts on Array prototype methods:

Not only will you uncover all common practices and syntax you need to use on a daily basis, I’ve also included a lot of hints and tips from over the years writing JavaScript.

Now it’s time to dive into array Map!

What is Map?

Map is a method that exists on the Array.prototype. It provides a way for us to loop over an array of elements and return a new value for each iteration.

This is typically called “mapping” over an array.

Those new values are stored and given to us as a new array - in the same order our original array was stored.

Here’s the syntax for the Map method in JavaScript:

const returnValue = array.map(callback[, thisArg])

Map was introduced in ES5 as a new helper method. I’d encourage you to also read the Array.prototype.map specification.

The first argument is a callback function, which is given three arguments, currentValue, the index and the current array (much like ForEach!). The callback function is invoked on every item in the array, passing us the item in the array as well as it’s index.

The second is the (optional) this context, should you wish to pass a new object as a reference to change the execution context.

Map returns a new array as the return value. Typically we would loop our array and perform a transformation, to one, many or all items in that array - and let map construct a new outputted array for us - containing those changes.

Using Map in JavaScript

In this next section, we’ll explore when to use Map and look at some array Map examples in JavaScript. I’ve also thrown in an example of using Map without Array.prototype.map so you can compare the “old” way of doing things!

When To Use Map

The time to reach for Map is when you need to iterate over an array, access each value and return either the same value or a changed value. After the Map has completed, all of the new values will be available in a new array. References are shallow-copied.

Generally, Map is a really common looping tool to map over your data structures, for example to perform operations on them and return new calculated values.

As Map accepts a callback function, it’s important to note that this will create new function scope. A traditional looping approach via a for...in will not create new function scope on each iteration.

Array Map example

Let’s look at how we map an array of elements Map. Here’s our data structure, a nice array with some objects inside:

const items = [
  { id: '🍔', name: 'Super Burger', price: 399 },
  { id: '🍟', name: 'Jumbo Fries', price: 199 },
  { id: '🥤', name: 'Big Slurp', price: 299 }
];

A most basic map gives us each item in our array, as well as its index position (if you need it!).

Let me demonstrate how we can use Map to halve the price of our 'Jumbo Fries' - something we may encounter if for example a user entered a coupon or we’re applying a “deal”…

const friesHalfPrice = items.map(function(item, index) {
  if (item.id === '🍟') {
    return {
      ...item,
      price: item.price / 2
    };
  }
  return item;
});

// log the return value!
console.log(friesHalfPrice);

We go and find the particular item using item.id and compare it to a string literal. It’s typical this could be a unique database ID in a production environment.

The above output would then give us:

[
  { id: "🍔", name: "Super Burger", price: 399 },
  { id: "🍟", name: "Jumbo Fries", price: 99.5 },
  { id: "🥤", name: "Big Slurp", price: 299 }
]

The good news is that we’ve created a new array and our original items remains untouched. We have a new collection now that we can do something with.

That was pretty easy to map an entire data structure and change some object properties (without mutating the existing array)! This practice of creating new arrays intead of mutating an existing array is called an “immutable operation”. A mutable operation would mutate the initial array, whereas we leave it untouched always. I hope this opens up some doors for you in your JavaScript programming.

Check it out:

So, you now know how to map over each array element and perform an action to compose a new array!

Bonus: Mapping without Map

Using a traditional for...in approach, here’s traditionally what one would have to write to achieve a map. Here’s a side-by-side comparison of the newer array Map approach versus the traditional imperative mapping:

// Declarative approach: Array.prototype.map
const friesHalfPriceDeclarative = items.map((item) => {
  if (item.id === '🍟') {
    return {
      ...item,
      price: item.price / 2
    };
  }
  return item;
});

// Imperative approach: For...in Mapping
const friesHalfPriceImperative = [];

for (let i = 0 ; i < items.length; i++) {
  const item = items[i];
  if (item.id === '🍟') {
    friesHalfPriceImperative.push({
      ...item,
      price: item.price / 2
    });
  } else {
    friesHalfPriceImperative.push({
      ...item
    });
  }
}

Both friesHalfPriceDeclarative and friesHalfPriceImperative will contain identical values.

This also demonstrates us the power and flexibility of using Map and other array prototype methods. The code is far smaller, promotes better practices, is easier to read and far more contained.

Note “Declarative approach” and “Imperative approach”. Declarative follows a more functional programming style which uses pure functions. Pure functions are easier to reason with, provide nice unit testing and allow us to chain operations together through a series of operators such as .map().filter().

The Map operator also produces new shallow copies of your array rather than mutating existing arrays. These practices tend to be preferred by the community as they produce no unintended side-effects (that may occur with more traditional code patterns and practices).

Summary

Map is the next best place to begin after getting started with array ForEach. Moving from a traditional for...in loop, the Map method can be introduced to bring a more functional approach and style to your programming.

If you’re enjoying this series, please keep following! To learn more JavaScript practices at this level and comprehensively, I’ve put together some online videos that explore the entire JavaScript language and the DOM - I’d encourage you to check them out if you are serious about JavaScript.

You’ve now learned how to use a Map to map over an array in JavaScript! Here’s a brief recap of what we’ve talked about and some extra details:

  • Use Map to create a new collection with changed values of your initial collection
  • Don’t forget to return or your values will be undefined
  • Map will shallow copy your object references into the new array
  • Don’t encourage bad habits by using .map() over .forEach() just because it can have the same effect and is ‘shorter’ - use the right tool for the right job or you will confuse people!
  • You can access the array you’re looping in the third argument of the callback
  • You can change the this context via a second argument to .map(callback, thisArg) so that any references to this inside your callback point to your object
  • You can use arrow functions with Map but remember that this will be incorrect if you also supply a thisArg due to arrow functions not having a this context
  • Like ForEach and friends, you cannot Map in reverse or break a Map, use for...in or for...of
  • Using Map will skip empty array slots
  • You shouldn’t need to in this day and age of evergreen browsers, but use a polyfill for older browsers if necessary

Thanks for reading, happy mapping!

Go to the next article in this series - Exploring Array Filter!

Love the post? Share it!

Lots of time and effort go into creating all our blogs, resources and demos, we'd love if you'd spare a moment to share this one!