Maps and Sets

Both Map and Set are new data structures introduced with ES6. They combine the properties of the pre-existing data structures: arrays and objects and offer advantages in certain non-typical use cases.

Maps

Concepts

A map (not to be confused with the array map method) introduces something like the associative array model to JavaScript. Prior to ES6 the closest thing JS had to this was an object.

Maps are like objects in that their structure consists in key/map pairs but like arrays in that the order in which the entries are placed is retained and can be referred to throughout the lifecycle of the Map. Also, the length of the Map is a known and easily returnable quantity, with objects we have to do some wrangling with Object.keys and Object.entries to retrieve meta data about the object itself. Moreover, with an object the order in which the keys are stored is not recorded.

At the same time Maps are different from arrays because the index of an array element is not unique, it will always be a number of the form [0], [1], [2]... .

Finally, the key can be any data type not just a string. This is an important characteristic of maps because although you can use numbers or booleans as the keys in an object, they are not actually numbers, they are converted to strings at execution. With Maps, whatever data type you assign as a key, retains its type.

Maps

  • Have key/value pair structure
  • Have length property
  • Order of entries and insertions is maintained
  • Can use any data type as a key
  • Disallow duplicate keys

Creating a Map and adding entries

const map = new Map();

// We then pass in key/value pairs using `set`:
map.set("firstName", "Luke");
map.set("lastName", "Skywalker");
map.set("occupation", "Jedi Knight");

There is an alternative method for defining a map:

const map = new Map([
  ["firstName", "Luke"],
  ["lastName", "Skywalker"],
  ["occupation", "Jedi Knight"],
]);

Internally, this data will be represented as follows:

Map(3)
0: {"firstName" => "Luke"}
1: {"lastName" => "Skywalker"}
2: {"occupation" => "Jedi Knight"}

Working with map elements

// check for the existence of an item in a map by searching for existence of key
map.has("firstName"); // return boolean

// return all keys in a Map as iterator
map.keys(); // MapIterator {'firstName', 'lastName', 'occupation'}

// return all values as iterator
map.values();

// return array of key/value pairs
map.entries(); // {"firstName" => "Luke", "lastName" => "Skywalker", "occupation" => "Jedi Knight"}
// retrieve an item from a Map
map.get("lastName"); // Skywalker

// delete an item from a map by key, returns boolean as confirmation
map.delete("occupation"); // true

//return the length of a map (just like array.length)
map.size; // 3
// clear all values
map.clear();

Looping

// Map has its own .forEach method, like with arrays. Hewre they are side by side

// Map
Map.prototype.forEach((value, key, map) = () => {})

// Array
Array.prototype.forEach((item, index, array) = () => {})

// You can also use a for of loop
// Destructure the key and value out of the Map item
for (const [key, value] of map) {
  // Log the keys and values of the Map with for...of
  console.log(`${key}: ${value}`)
}

Interfacing between Maps and other reference types

Given that we can create a map with both object and array-style syntax, its easy to convert maps to and from the more established data structures.

It’s easy to convert an object to a map:

const luke = {
  firstName: "Luke",
  lastName: "Skywalker",
  occupation: "Jedi Knight",
};

const map = new Map(Object.entries(luke));

And a map to an object:

const obj = Object.fromEntries(map);

A map to an array:

const arr = Array.from(map);

We saw earlier that a Map is a multidimensional array, so any multidimensional array can be used in the Map constructor invocation to turn it into a Map.

Sets

A set is special kind of array, an atypical supplement to arrays. It is basically an array of unique values. If you try to add a duplicate entry to a set it will be ignored.

const set = new Set();
set.add("Beethoven");
set.add("Bach");

// Or:
const set = new Set(["Beethoven", "Bach"]);

// Convert array to set (note, this will remove duplicates on initialisation)
const arr = [...set];

We can use keys(), values(), and entries() with sets but obviously, keys and values will be identical.