The Map Object For JavaScript
One of the quintessential data structures in computer programming is the map, also known as a dictionary or associative array. Each programming language uses this data structure with subtle functional differences. For example: Ruby
uses Hash
, Python
uses Dictionary
, and JavaScript
uses Object
. The commonality of these map variants is the ability to store a list of key-value pairs. The syntax used is a set of braces which contain comma-separated entries, which are represented as a key and value separated by a colon, i.e. {key1: value, key2: value}
.
The keys of a map must be unique. Maps provide a helpful structure for storing data that is powerful for look-up and searching. So long as the key is known, the value can be immediately and directly accessed. Historically, the Object
was used as a map data structure for JavaScript
, but a newer complement has joined the fold: the Map
object. Both have merit, and performance superiority depending on use cases. There are a lot of great articles and documentation on the newer Map
object (which should be explored!), but, for this article, I simply aim to introduce and illustrate its prime advantages.
*Aside: In JavaScript
, keys are typically referred to as properties.
Key Types:
While an Object
can only have keys of string
or symbol
data type, Map
can have keys of any data type. This provides flexibility and consistency. If one were to create an Object
with numeric keys, they would be automatically coerced into strings
. A Map will maintain the data type of initialized keys.
const object = new Object()object[1] = 'one'console.log(object)
//=> {'1': 'one'}====================================================================const map = new Map()map.set(1, 'one')console.log(map)
//=> Map {1 => 'one'}
Both examples initialize a key-value pair with a key of 1
. In the case of the Object
, the key is coerced into the string
'1'
. In the case of the Map
, the key remains the number
1
. Also, note the difference in protocol for adding a key-value pair. An Object
requires bracket notation (or dot notation) and a Map
uses a built in method called .set()
.
Size:
Unlike an Object
, a Map
has a built in property to determine its size.
const map = new Map()map.set(1, 'one').set('two', 2) //notice method chainingconsole.log(map.size)
//=> 2
The equivalent protocol for determining the size of an Object
requires using the .entries()
method or .keys()
method to produce an Array
of key-value pairs or keys, respectively, then calculating the length of the Array
.
const object = new Object()object[1] = 'one'
object['two'] = 2
const entries = Object.entries(object)console.log(entries.length)
//=> 2
This comparison may seem like split hairs, but imagine the computational difference if the queried size was of a massive data set.
Key Order & Iteration:
While since ES6
Objects
do preserve creation order for string
and symbol
keys, there can remain compatibility issues. The entries of a Map
are patently ordered, by insertion, which is consistent and predictable. This ties in nicely with what, in my opinion, is the real bread and butter of the Map
object: it can be directly iterated. The key-value pairs of an Object
can be iterated if first transformed into an array (e.g. .entries()
) or by using a for…in
statement (which is best suited for debugging), but a Map
is truly iterable, and even has a built in .forEach()
method akin to that of an Array
.
const map = new Map()map.set(1, 'make')
.set(2, 'these')
.set(3, 'big')console.log(map)
//=> Map {1 => 'make', 2 => 'these', 3 => 'big'}// required parameters: v = value, k = key, m = map
// m being the Map object the method is being called on
map.forEach((v, k, m) => m.set(k, v.toUpperCase()))console.log(map)
//=> Map {1 => 'MAKE', 2 => 'THESE', 3 => 'BIG'}====================================================================const map = new Map()map.set('lydia', 'beetlejuice')
.set('barbara', 'beetlejuice')
.set('adam', 'beetlejuice')console.log(map)
//=> Map {
'lydia' => 'beetlejuice',
'barbara' => 'beetlejuice',
'adam' => 'beetlejuice'
}for (const e of map) {
let exclamation
[k, v] = e switch (k) {
case 'lydia':
exclamation = '!'
break
case 'barbara':
exclamation = '!!'
break
case 'adam':
exclamation = '!!!'
break
default:
exclamation = ''
} console.log(`${v.toUpperCase()}${exclamation}`)
}//=> BEETLEJUICE!
//=> BEETLEJUICE!!
//=> BEETLEJUICE!!!
In a nutshell, Map
nor Object
are better than the other, but they each have strengths to be applied in different situations. Generally speaking, a Map
is a good tool for large data sets, and where frequent insertion, deletion, alteration, or access of key-value pairs is necessary. An Object
is the true cornerstone of JavaScript
, and it is an intrinsic and versatile tool that can be used like a map to store data and much more. Don’t reach for a hammer when a hand will do. I encourage you to research the documentation and discover more intimately the capabilities of both Map
and Object
, and I hope this article clued you in to the possibilities of Map
if you weren’t already aware!
github.com/dangrammer
linked.com/in/danieljromans
danromans.com