Write more readable code in JavaScript using the map array method

There are lots of array methods in JavaScript. map helps you to write non-mutating readable code in JavaScript.


The array is one of the most common data types in JavaScript. There are many useful methods associated with arrays like map, filter, reduce, find, some, forEach, push, pop, etc. In this article, I am gonna talk about map method.

map is a non-mutating method. So, if you do things right, the main array elements will not be affected (modified).

Map

map method creates a new array with the same length from the original array. It is very helpful when you need to create a new array from the original array and you also want to do some operations on each item in the array.

map structure:

const resultingArray = oldArray.map((currentValue, index, oldArr) => {
  // return an element
}, this);

map expects two parameters.

  1. callback function. This does the main job. We can use traditional function. Or ES6 arrow function. In our case, (currentValue, index, oldArr) => { // return an element } this is the callback function.
  2. this argument. You can use it as this value in the callback function. It is optional and rarely used.

Now, callback function has 3 arguments.

  • currentValue. This is the element or value being processed in every loop iteration.
  • index. This is optional. This represents the index of currentValue.
  • array. This is also an optional and rarely used argument. This represents the original array on which map method was applied.

After processing, map returns the resultingArray without modifying oldArray.

Example:

const persons = [
  { name: "Jane", age: 19 },
  { name: "John", age: 21 },
  { name: "Rick", age: 17 },
  { name: "David", age: 22 },
];

const names = persons.map((person) => person.name);
/*
 * ES5 function syntax:
 * const names = persons.map(function (person) {
 *   return person.name;
 * });
 */

console.log(names);
// output: ['Jane', 'John', 'Rick', 'David']

In this example, we have created a new array containing only names. In the map function, I am passing a function which takes a person and returns that person's name. So, it loops through the array, for every element in that array, it returns only the name property hence creates a new array with only names.

If we wanted an array containing name and a flag to determine if the person is 20 plus aged, then we could do the following:

const persons = [
  { name: "Jane", age: 19 },
  { name: "John", age: 21 },
  { name: "Rick", age: 17 },
  { name: "David", age: 22 },
];

const newPersons = persons.map((person) => {
  return { name: person.name, twentyPlus: person.age > 20 };
});

/*
 * ES5 function syntax:
 * const newPersons = persons.map(function (person) {
 *   return { name: person.name, twentyPlus: person.age > 20 };
 * });
 */

console.log(newPersons);
/* output:
 * [
 *   { name: 'Jane', twentyPlus: false },
 *   { name: 'John', twentyPlus: true },
 *   { name: 'Rick', twentyPlus: false },
 *   { name: 'David', twentyPlus: true }
 * ]
 */

In this example, we have created a new array containing names and a flag to determine if the person's age is more than twenty or not. In the map function, I am passing a function which takes a person and returns a new object. That object contains the person's name and a flag to determine if the person's age is more than twenty or not. So, it loops through the array, for every element in that array, it returns the name property and that boolean value wrapped in an object hence creates a new array with names and twentyPlus flag.

Now in the first example, I used shorthand syntax to return name and in the second example, I returned the new object explicitly.

We can use normal callback function instead of ES6 arrow function. But, arrow functions are more readable.

I will now share another example with index and array in callback function:

const persons = [
  { name: "Jane", age: 19 },
  { name: "John", age: 21 },
  { name: "Rick", age: 17 },
  { name: "David", age: 22 },
];

// index will add 0, 1, 2, 3 respectively and array.length will
// add 4 for every new item's modifiedAge property
const newPersons = persons.map((person, index, array) => {
  return { name: person.name, modifiedAge: person.age + index + array.length };
});

// ES5 function syntax:
// const newPersons = persons.map(function (person, index, array) {
//   return { name: person.name, modifiedAge: person.age + index + array.length };
// });

console.log(newPersons);
// Output:
// [
//   { name: 'Jane', modifiedAge: 23 },
//   { name: 'John', modifiedAge: 26 },
//   { name: 'Rick', modifiedAge: 23 },
//   { name: 'David', modifiedAge: 29 }
// ]

All modern browsers support map. You can find complere reference here

When not to use map

map is not for every situations. When you do not want or need to return value or create new array with the same length, map should not be used. forEach or other array methods should be more suitable on those situations.

Why map is more readable

Suppose, you are creating a new array of persons with name and twentyPlus boolean flag like our second example with traditional for loop. Then, the code should be like this:

let newPersons = [];
for (let i = 0; i < persons.length; i++) {
  let person = {
    name: persons[i].name,
    twentyPlus: persons[i].age > 20,
  };
  newPersons.push(person);
}

You have to go through the whole code to understand that I am creating a new array. And the main logic of creating that array resides inside person object creation part inside the for loop. You will also have to check if I have written a break or continue statement to skip any particular value or not.

On the other hand, as soon as you see a map method, you know that I am creating a new array of the same length. As new array must be of the same length, I cannot use break or continue to skip values.

const newPersons = persons.map((person) => {
  return { name: person.name, twentyPlus: person.age > 20 };
});

When we use map, we can focus more on logic cause it's purpose is defined.

Conclusion

map is a very handy array method. It has a specific purpose. That purpose is: creating a new (modified) array with the same length. Whenever we need this functionality in our code, we should be using map for better readability and maintainability.