The Map Object in JavaScript

2023-02-11
By: O. Wolfson

As developers, we frequently work with data that needs to be stored and manipulated. In JavaScript, there are a number of built-in data structures that can be used for this purpose, including arrays, objects, and maps. In this article, we'll take a closer look at the Map object in JavaScript, and how it can be used to store and manipulate key-value pairs.

What is a Map Object?

A Map object is a built-in data structure in JavaScript that allows you to store key-value pairs. It is similar to a JavaScript object, but with a few key differences. One of the main differences is that in a Map object, the keys can be any type of value (including objects, functions, and other non-primitive types), whereas in a JavaScript object, the keys can only be strings or symbols. Another important difference is that a Map object preserves the order of its elements, whereas the order of keys in a JavaScript object is not guaranteed.

A Real-World Example: Finding the Top Films in the Star Wars Universe

To demonstrate the use of the Map object, let's consider a scenario where we have a list of top Star Wars universe films, and we want to find the top 3 films based on their ranking across different lists. For this purpose, we can use the findTopFilmsWithPosition() function, which takes an array of film lists as input and returns the top 3 films based on their average ranking across all lists.

Here's a sample dataset that we can use for this example:

javascript
const filmLists = [
  [
    "The Empire Strikes Back",
    "A New Hope",
    "Return of the Jedi",
    "The Force Awakens",
    "The Last Jedi",
  ],
  [
    "A New Hope",
    "The Empire Strikes Back",
    "The Force Awakens",
    "The Last Jedi",
    "Return of the Jedi",
  ],
  [
    "The Empire Strikes Back",
    "Return of the Jedi",
    "A New Hope",
    "The Last Jedi",
    "The Force Awakens",
  ],
  [
    "A New Hope",
    "The Empire Strikes Back",
    "Return of the Jedi",
    "The Last Jedi",
    "The Force Awakens",
  ],
  [
    "The Empire Strikes Back",
    "A New Hope",
    "Return of the Jedi",
    "The Last Jedi",
    "The Force Awakens",
  ],
];

How to Find the Top Films

Let's create a function called findTopFilmsWithPosition() that works by iterating over each film list in the input array, and assigning a score to each film based on its position in the list. Films that appear earlier in the list receive a higher score. The function then uses a Map object to keep track of the score of each film across all lists, and returns the top 3 films based on their average score.

Why use a Map Object?

In this particular case, a Map object is a better choice than, say, a JavaScript object. There are a few reasons why using a Map object is a better choice:

Clarity: Using a Map object in this case makes it clear that we are storing key-value pairs, where the key is a film name and the value is the film's score. This is more semantically meaningful than using a JavaScript object, which is a more general-purpose data structure that can be used for many different purposes.

Performance: When you are working with a large number of key-value pairs, Map objects are generally more performant than JavaScript objects. This is because Map objects are optimized for this use case, whereas JavaScript objects are optimized for general-purpose use cases.

Order: Map objects preserve the order of their elements, whereas the order of keys in a JavaScript object is not guaranteed. In this case, we need to preserve the order of the films in order to correctly calculate the score of each film, so a Map object is a better choice.

Overall, while a JavaScript object could technically be used in this case, a Map object is a better choice because it is more semantically meaningful, more performant, and better suited for this particular use case.

Implementation

Here's the implementation of the findTopFilmsWithPosition() function, with comments explaining how it works:

javascript
function findTopFilmsWithPosition_commented(films) {
  // create an empty Map object to store the score of each film
  const scores = new Map();
  // set the number of lists to the length of the input array
  const numLists = films.length;

  // loop through each list in the input array
  for (let i = 0; i < numLists; i++) {
    // get the current list
    const list = films[i];
    // get the length of the current list
    const listLength = list.length;
    // loop through each film in the current list
    for (let j = 0; j < listLength; j++) {
      // get the current film
      const film = list[j];
      // assign a position score based on the position of the film in the list
      const positionScore = 1 / (j + 1); // higher score for films appearing earlier in the list
      // update the score of the film in the Map object
      if (scores.has(film)) {
        // if the film is already in the Map, add the position score to its existing score
        scores.set(film, scores.get(film) + positionScore);
      } else {
        // if the film is not yet in the Map, set its score to the position score
        scores.set(film, positionScore);
      }
    }
  }

  console.log("scores:", scores);

  // create an empty array to store the top 3 films
  const topFilms = [];
  // loop 3 times to get the top 3 films
  for (let i = 0; i < 3; i++) {
    // initialize the top score and top film to null
    let topScore = 0;
    let topFilm = null;
    // loop through the Map object to find the film with the highest score
    for (const [film, score] of scores.entries()) {
      // if the score of the film is higher than the current top score and it hasn't already been added to the top films array, update the top score and top film
      if (score > topScore && !topFilms.includes(film)) {
        topScore = score;
        topFilm = film;
      }
    }
    // if a top film was found, add it to the top films array
    if (topFilm !== null) {
      topFilms.push(topFilm);
    }
  }

  // return the top films array
  return topFilms;
}

The output of this function, based on the sample data, is ["A New Hope", "The Empire Strikes Back", "Return of the Jedi"], which are the top three films based on their average ranking across all of the lists.

The map object:

json
{
  "The Empire Strikes Back": 2.6,
  "A New Hope": 2.4,
  "Return of the Jedi": 2.4,
  "The Force Awakens": 1.8,
  "The Last Jedi": 1.8
}

Now that we've seen the Map object in action with a specific use case, let's delve deeper into what it is and how it works.

Understanding the Map Object

In JavaScript, a Map is a collection of key-value pairs where each key is unique. Unlike an Object, a Map allows any type of data to be used as a key, not just strings or symbols. A Map also maintains the order in which key-value pairs were added, which is not guaranteed with an Object.

The syntax for creating a Map is as follows:

javascript
const myMap = new Map();

We can also create a Map from an array of key-value pairs using the Map constructor:

javascript
const myMap = new Map([
  ["key1", "value1"],
  ["key2", "value2"],
  ["key3", "value3"],
]);

We can then access the values stored in the Map using the get method, passing in the key:

javascript
const value = myMap.get("key1");
console.log(value); // Output: 'value1'

We can also use the set method to add new key-value pairs to the Map:

javascript
myMap.set("key4", "value4");

We can check if a key exists in the Map using the has method:

javascript
const hasKey = myMap.has("key1");
console.log(hasKey); // Output: true

To remove a key-value pair from the Map, we can use the delete method:

javascript
myMap.delete("key1");

And to get the number of key-value pairs in the Map, we can use the size property:

javascript
const size = myMap.size;
console.log(size); // Output: 3

Conclusion

The Map object is a powerful tool in JavaScript that allows for the storage of key-value pairs, with unique keys and maintained order. The findTopFilmsWithPosition function we looked at is just one example of how the Map object can be used to solve complex problems. By using the Map object, we were able to efficiently determine the top films from a set of data.

I hope this article has given you a better understanding of the Map object in JavaScript and how it can be used in your own projects. Happy coding!