Why Use .map() When a For Loop Is Just as Good?

Imagine I have an array of integers from 0 through 9:

const numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];

If I want a new array where each element is the square of each element in numbers, I might try doing it like this:

const squares = [];
for (const number of numbers) {
  squares.push(number * number);
}

In JavaScript, however, we can use .map() to achieve the same thing, which is a concise way to apply a function to each element in an array and collect the results.

Here’s how we’d do it using .map():

const squares = numbers.map((number) => number * number);

After introducing .map(), my students often ask, "Why use .map() when a for loop seems easier to understand?"

I sometimes muddy things by explaining that .map() can be faster, or that functional programming techniques are useful for distributed systems (since they avoid modifying the original data), or that using .map() is simply more elegant.

But, honestly, these aren’t the best answers. The real answer, and the better answer, is that .map() and for loops are meant to do two completely different things. That they use similar keywords and both involve iterating over arrays is just a coincidence that can create confusion.

Here’s the essential distinction:

for loops are intended to perform an action multiple times. For example, if you have an array of filenames and want to delete each file, then you should use a for loop. The purpose of a for loop is the action -- the side effect -- not the result returned by that action.

Here are some examples to illustrate typical for loop use cases:

  • Submit the Scrabble score for each word in a sentence to a server:

    for (const word of sentence.split(" ")) {
      submitScore(scrabbleScore(word), username, server);
    }
    
  • Ping each IP address to check if the computer is running:

    const isRunning = {};
    for (const ipAddress of ipAddresses) {
      isRunning[ipAddress] = pingIP(ipAddress);
    }
    

    Here, I’m assuming pingIP is a function that does more than just return a value; it performs an actual network action. Otherwise, I’d likely create an object using .map() or a reduce to accumulate the values.

  • Attempt to copy a file to a remote server up to five times:

    for (let attempt = 0; attempt < 5; attempt++) {
      if (copyFile(filename, serverInfo)) break;
      console.log(`Attempt ${attempt} failed; trying again`);
    }
    

So, as you can see, I use a for loop when I’m not focused on getting back a particular result but rather when I need to perform an action for each element in a collection.

In contrast, if I’m interested in obtaining a new array — either for direct use or as input to create another structure — then .map() or .filter() is more appropriate. For instance:

  • Get usernames from a list of user data:

    const usernames = users.map((user) => user.username);
    
  • Convert lines from a configuration file into key-value pairs:

    const config = lines.map((line) => line.split(":"));
    
  • Summing an array of hex numbers into integers:

    const hexNums = "123 abc 1a2b 3f4e";
    const sum = hexNums
      .split(" ")
      .map((hex) => parseInt(hex, 16))
      .reduce((a, b) => a + b, 0);
    

    In these cases, I’m interested in transforming the input into a new array or value, so .map() is an ideal choice.

Ultimately, the distinction between for loops and .map() isn’t about performance, elegance, or functional style. The main question is whether your goal is to perform an action for each element in a collection or if you want to create a new collection by applying an expression to each input from an iterable.

Does this make .map() a bit more accessible? I hope so!

Learn Higher-Order Functions

Write code that is easier to understand and maintain.

You've heard about higher-order functions, but every explanation you've come across is either too technical or too vague. You're searching for something clear and practical, with examples that will help you practice and truly master the concept.

Higher-order functions are key to writing better code, essential for your projects, and expected in interviews. But getting started can be tough.

But what if you could? What if you had access to easy-to-understand content that not only explains higher-order functions but also provides hands-on practice? You’d finally feel confident using them in your projects, knowing exactly what they do and how to leverage them effectively.

It’s true, finding the right resources to learn higher-order functions can be challenging… but it doesn’t have to be.

Get my guide, where you’ll:

  • Understand why higher-order functions are worth learning and how they can transform your approach to writing JavaScript.
  • Gain clarity as I break down higher-order functions into simple, everyday language.
  • Master three important higher-order functions: map, filter, and reduce, with plenty of examples to solidify your understanding.
  • Apply your knowledge with real-world examples that demonstrate how these concepts work together, so you can use them easily in your projects or write better code in your interviews.
  • Get practice exercises to help reinforce what you’ve learned and boost your confidence in understanding the concepts.

Get the Guide