Map.prototype in JavaScript
…not to be confused with Array.prototype.map()
Whelp, I bombed yet another timed technical assessment!
I was warned that it would “be heavily focused on object-oriented programming principals,” so I thought I was finally golden. I brushed up on static and instance methods. Constructors, inheritance — I was ready to go! I opened it up and BAM! There in the constructor:
constructor() {
this.hosts = new Map();
}
Map? Capitalized? WTF is that. In all of my single year of coding how has this object never come across my desk??
According to MDN “The Map
object holds key-value pairs and remembers the original insertion order of the keys.”
In hindsight I probably could have gotten away with creating an Object to solve this problem. But the clock was ticking, they’d provided base code utilizing a Map, and based on the prompt and the Map definition, I thought that the order of the items added would matter. So after thirty sad, sad minutes in a strange IDE where I couldn’t find any of my console.logs, writing a “well, that happened email,” and a night of Animal Crossing I woke up and learned this awesome new tool for my toolbox!
Map
Map looks a lot like an Object, but it has some pretty sweet built in methods that allow you to operate on it in a pretty handy way!
Map.set
const bubbleTeaShop = new Map()bubbleTeaShop.set('boba', 5)
bubbleTeaShop.set('aloe jelly', 2)bubbleTeaShop
// Map(2) {'boba' => 5, 'aloe jelly' => 2}
The first argument here is the key, the second argument is the value. And if you’re updating the value, the syntax is the same:
bubbleTeaShop.set('aloe jelly', 3)
// Map(2) {'boba' => 5, 'aloe jelly' => 3}
You can also add multiple items at once with chaining:
const bubbleTeaShop = new Map()bubbleTeaShop.set('boba',5)
.set('aloe jelly', 4)
.set('red bean', 9)
Map.entries(), .next(), and the iterator
Unlike a JavaScript Object, Map keeps track of insertion order! And just to prove that this is insertion order, and not update order, I will update one of the values before we call the iterator:
const bubbleTeaShop = new Map()bubbleTeaShop.set('boba',5)
.set('aloe jelly', 4)
.set('red bean', 9)bubbleTeaShop.set("aloe jelly", 5)
// Map(3) {'boba' => 5, 'aloe jelly' => 5, 'red bean' => 9}let iterator = bubbleTeaShop.entries()
// undefinediterator.next().value
// (2) ['boba', 5]iterator.next().value
// (2) ['aloe jelly', 5]iterator.next().value
// (2) ['red bean', 9]
Map.get()
This will retrieve the value at a given key:
bubbleTeaShop.get("aloe jelly")
// 5
Map.has()
Returns true or false depending on whether or not the ingredient is present:
bubbleTeaShop.has("aloe jelly")
// true
In a function:
Here we can utilize .has(), .get() and .set() to dynamically access and update our Map.
function addIngredient(shop, ing, amount){
if (shop.has(ing)){
shop.set(ing, (shop.get(ing))+amount)
} else {
shop.set(ing, amount)
}
}const bubbleTeaShop = new Map()bubbleTeaShop.set('boba',5)
.set('aloe jelly', 4)
.set('red bean', 9)addIngredient(bubbleTeaShop, "lychee jelly", 2)
addIngredient(bubbleTeaShop, "red bean", 3)bubbleTeaShop
// Map(4) {'boba' => 5, 'aloe jelly' => 4, 'red bean' => 12, 'lychee jelly' => 2}
Is this better than a JavaScript Object? Jury’s out. I’m going to keep working with it and see if I can find a use case for that iterator. For the time being, I do appreciate the built in functions as being easier to read than the typical object modification syntax!
And here are a few other helpful built in functions you can use with Map via MDN: