Using .map

Monday, June 1, 2020

The .map function is something I use pretty much every day when developing. It's one of those functions that once when you understand what it does, you will find out it comes in handy in most situations.

What is .map?

According to the MDN docs, an explanation for this function would be:

The map() method creates a new array populated with the results of calling a provided function on every element in the calling array.

So what does this mean in simple terms?

  1. You call .map on an array
  2. .map creates an empty array
  3. .map receives a function
  4. That function gets called on every element in the array
  5. It returns the value of that function into the array

Basically, .map is used when you want to transform values in an array and return those to a new array.

An Example

Let's say we have this array below.

const arrayOfNumbers = [2, 8, 42];

And we wish to double every number in that array, and return it to another array.

In the past, I would have done this:

const arrayOfNumbers = [2, 8, 42];
const results = [];
 
arrayOfNumbers.forEach((number) => results.push(number * 2));
 
// results now equals [4, 16, 84]

Or even:

const arrayOfNumbers = [2, 8, 42];
const results = [];
 
for (let index = 0; index < arrayOfNumbers.length; index++) {
  const numberToMultiply = arrayOfNumbers[index];
  const numberMultiplied = numberToMultiply * 2;
 
  results.push(numberMultiplied);
}
 
// results now equals [4, 16, 84]

As we can see, it works. It's a solution to the problem. But how can this be improved upon?

Introducing .map

Before I show you the difference, it's good to know what .map gives you when calling it.

/**
 * number - This the the element .map is currently looping over
 * index - this is the index of the current element
 * array - The array you called .map on
 */
const results = arrayOfNumbers.map((number, index, array) => {
  //...
});

Using .map

const arrayOfNumbers = [2, 8, 42];
const results = arrayOfNumbers.map((number) => number * 2);
 
// results now equals [4, 16, 84]

Okay, so what did that do except for saving us two lines of code? As you can see, we don't need to create an empty array and then push to that. .map returns every result into an empty array by default.

It's so much easier to read. There are no extra variables to keep track of, .map creates an empty array and fills that with the results by itself.

Let's look at another example where .map shines.

Transforming data

The previous example was a very simple one in terms of the data we had to transform. This would be a more realistic example of what you could encounter while developing.

This time, this will be the data we work with:

const data = [
  {
    id: 1,
    name: "John",
    job: "Barista",
  },
  {
    id: 2,
    name: "Mary",
    job: "Developer",
  },
  {
    id: 3,
    name: "Max",
    job: "Accountant",
  },
];

Retrieve all jobs

Like I mentioned earlier, .map loops over all the data in an array. In this case, it would loop over all the objects.

If we wanted to get all of the jobs, we could use .map like this:

// data array left out to keep this short
 
const allJobs = data.map((user) => {
  return user.job;
});
 
// returns ['Barista', 'Developer', 'Accountant']

Did you know you can give .map a function?

function getJobFromUser(user) {
  return user.job;
}
 
const allJobs = data.map(getJobFromUser);

In this example, I think it does not help with making the code more readable. The example before it was way easier to scan and understand, but it might come in handy if the data manipulation becomes more complex.

Rendering components in React

I won't go too much into details on React to keep this blog post focused on .map, but this is definitely something that you will see a lot when working with React.

If you want to render a list of items based on data, .map comes in really handy.

() => {
  const data = [
    {
      id: 1,
      name: "John",
      job: "Barista",
    },
    {
      id: 2,
      name: "Mary",
      job: "Developer",
    },
    {
      id: 3,
      name: "Max",
      job: "Accountant",
    },
  ];
 
  return (
    <div>
      {data.map((user) => {
        return <li key={user.id}>{user.name}</li>;
      })}
 
      {/* As you can see below (remove comment), arrays of JSX render to React! */}
      {/* {[<li>test</li>]} */}
    </div>
  );
};

React will return an array of JSX elements, which in turn gets rendered!

Closing thoughts

Hopefully, this post has been able to give you a better idea of what .map does and when to use it. I think this is a staple function that every developer should know about.

I do think it is valuable to start with the basics, using for loops or forEach loops. In the past, these were the tools you would grab, and understanding where we came from makes us appreciate the new tools more.