Instructor: Welcome back, I will now show you
something that is entirely new is ES6,
and that's a new data structure called map.
And in case that you're wondering,
this doesn't have anything to do with actual maps
like you see on Google Maps or something.
So let me explain what maps are in ES6.
So a very common use of JavaScript objects
is to use them as hash maps, which simply means
that we map string keys to arbitrary values,
and we did that a lot earlier in the course.
Especially in the basic section, for example,
in our more simple John object.
Back then we had simple keys like name, age or job,
and then mapped values to them, like John, 27 and teacher.
Now this is called a hash map, and up until ES6,
we had to use objects for that, but now in ES6,
we have something better, and that's maps.
So a map is a new key-value data structure in ES6,
and one of the big differences is that in maps,
we can use anything for the keys.
So in object we are limited to strings,
but in maps we can use any kind of primitive value
like numbers, strings or Booleans,
and we can even use functions or objects as keys,
which is really cool, and really a big deal.
All right, but enough theory, let's actually use this
in practice, and construct our first map,
and we're gonna implement a very, very simple quiz
with only one question, just to show you how maps work.
So this is how we create a map.
Let's create a variable and it will be a constant,
and I'm just gonna call it "question,"
and we say we want a new Map, and that's it.
So we just created a new empty map,
so let's now add some data to it, and in order
to do that, we use the "set" method.
So question.set, and then we set the key,
in this case I'm first gonna use a string so
that we can specify the question text in here.
So I say question, which is the key, and then the value,
and the question's gonna be "What is the official name
of the latest major JavaScript version?"
All right, and that's it, so this is
the first key of our new map.
So this works a bit like a property in an object, right,
so we could have a question property,
and then assign this string to that property,
so that would be similar, but in maps,
this is how we define a new key-value pair, okay?
And so let's now add some answers to this question,
so question.set, and now I can use,
as I said before, anything in here.
It doesn't have to be a string like an object,
it can be anything, and so I'm simply gonna say "1."
So 1 for the first answer, let's say "ES5," okay?
Okay, and another choice is "ES6," and let's add another one
so that we have multiple choices here.
"ES2015," and a fourth one, "ES7," here we go.
Okay, and now we also need the correct answer
so I'd add that as well, so that set,
and now I say "correct," so we're back to using a string
as a key here, and a correct answer is of course,
and I hope that you know it, number 3.
So this is the official name of
the latest JavaScript version,
actually the major JavaScript version
because ES7 is the most current version,
but that's not the one that everybody uses right now.
Everyone is rather focusing on ES2015 at this point.
All right, and what we can also add here is what happens
if the answer is true, or if it's false.
So let's put another key-value pair here,
and we already used strings as a key, we used numbers,
and now let's use a Boolean, okay?
So if the answer is true, then we want to print to
the console "Correct answer :D,"
and if it's the wrong answer, then of course it's false,
and then we say "Wrong, please try again!"
And so I think that with this,
we have everything set up for our question.
Let's now load this and take a look
at our map here in the console.
So question, and here it is, so this is how
a map looks like here in the console.
Let's open this, and so here we go.
Here we have our entries, we can also see the length,
and we see that the prototype of this map
is of course a map, so this is like,
remember like an array for example,
where the prototype is an array,
and so this is a new built in type in ES6, so a map.
And this of course, if we see the prototype chain
is an object and so on and so forth, right?
So just to see how this looks in a console.
Now what if we actually wanted to retrieve data from
this map, what we do is the opposite of set, which is get.
And so what we do is question.get,
and then we simply have to pass in the key,
so let's say that we want the question,
and let's console.log this,
and so we should see the value, and that's it.
So what's the official name of
the latest major JavaScript version?
Okay, and another cool thing that we can do
with maps, that we can't do with object,
is to get the size or the length.
So we can say question.size, and it's not length
like it's with arrays, but in this case it's size.
So let's see, and it gives us "8."
So this works, so one, two, three,
four, five, six, seven and eight.
So we can set data in our map and we can also get data,
but we can also delete data and check
if data is there, or if a certain key is there.
So imagine that we wanted to make this question
a bit easier, and in order to do that,
we would remove one of these choice elements, right,
so instead of having four, we would have only three.
So let's see how that works.
So it's actually very simple, so all we say
is question.delete, and then the key.
In this case we wanna remove the number 4.
All right, let's take a look at it now here in the console,
question, and so yeah, it's not here.
So 1, 2, 3, and 4 is gone.
Now what would happen if we would accidentally run
this line of code here twice, so delete it twice.
Let's duplicate and find out, actually nothing happens.
Let's check it out again, question.
So since it's not there, nothing happens,
but just to be sure we can use the "has" method.
So we can say if question has the key number 4,
then in this case let's delete it,
and actually this would be here, okay?
So we can get, set, delete and also check
if a certain key is in the map.
So if there's a key, number 4, in the question,
then we can delete that element,
and if you decide that you wanna delete
all of the elements at the same time,
then there's also a method for you,
and that one is called "clear."
So let's finally clear everything from our map,
so all we have to do is to use clear.
So if we now load this, and then check out our question,
then you see that it's empty.
So it's no longer there because we cleared everything.
Of course, we don't wanna do that right,
and we also don't want to delete
the question number 4, so let's just take this out,
and log something to the console here instead,
just to see that the "has" method works.
All right, so set, get, has, delete and clear are
the most basic methods that we can use to manipulate maps.
Now something else that's very cool
is that maps are actually iterable, so this means
that we can loop through them, which is another thing
that we cannot do with objects, right?
So the first way of looping through a map
is to use the "forEach" method, and so this means
that each map gets the forEach method such as arrays do,
and all this means is, as you already know,
is that the forEach method is in the prototype property of
the map function constructor, and so all of the maps inherit
that method and can then use it.
So let's try that, and so we say question.forEach.
And such as with arrays, we have access to
the current element, to the current key,
and also to the entire map.
So let's access the value and the key,
and I'm actually gonna call it like that, so value and key,
and let's just log them to the console, okay?
So console.log, this is key,
and it's set to, and of course it's the value.
So let's check this out, and yeah, so here we go.
So all our eight elements here are now printed to
the console, and so this means that we can really
loop through a map, which is really handy.
So we used it for each method,
but we can also loop using the "for-of" loop
that I showed you before with the arrays.
So this kind of loop doesn't only work for arrays,
but also for maps, so let's try that out as well.
So for, and let's say key, and then the of,
so for-of, question.
Now what if we wanted to access not only
the key, but also the value?
In this case we would once again have to use destructuring
and so this is yet another case of the destructuring.
So instead of simply using the questions variable,
like here, like I did here, we use question.entries.
So just like this, and what this does here
is to return all entries of our questions map,
and we can then use destructuring to store the key
and values in two separate values, such as we did before.
So remember, destructuring is using these brackets,
and so we simply say key and value.
So once more, using the entries method here on the question
is gonna return all the key-value pairs,
and we can then use destructuring,
such as we did before with arrays,
and store the keys and the values in two separate variables
that we can then use here inside of this for-of loop.
And actually, this also works for arrays,
so if you're curious about that, you can simply go try
that out and I'm sure that you're going to make it work.
So let's now do the exact same thing here
just to see if it works as well,
so I'm just gonna comment this one out
so that it doesn't get in our way.
So if I reload this now we actually get an error, and that's
because there's one parenthesis here too much, okay?
But now here we go, so everything works
as expected, as it did before.
So let's now, instead of printing all of the elements
in our map, let's use this to only print
our four answers here, okay?
And the way that we do this, is to say
that we only want to print the value if the key is a number.
So that's the beauty of having
this custom data type here for the key.
So remember, in maps, the key cannot only be strings,
but also like numbers or Booleans like down here,
and so we can use that to our advantage right now.
So we can say that if the type of the key is number,
and that's actually that we didn't do before,
so you're still learning a couple of new stuff here
in this section, which is great, right?
So we can use this built-in JavaScript function
to check the type of a variable.
And so in this case we only want to execute
this part of the code here if the key is a number,
and what we wanna do in this case,
is to simply console.log the answer, okay?
So Answer, then number key,
and then of course the value, and that's it.
Okay, and to make our question here look a bit better,
we just wanna get rid of this,
and of this output here, right?
So let's take this out, and this one as well.
This was just for testing purposes before.
So now we have our question and our four
answer possibilities, what we need to do next
is to actually get our answer, and we did that before
in one of the coding challenges, and I'm gonna do it again
right now using the "prompt" function,
which simply opens a pop-up window, and asks for an answer.
And I wanna declare it as a constant and call it "ans"
for answer, and then say prompt, "Write the correct answer."
So here the user can write one, two, three or four.
Now the problem with this is that JavaScript
will then interpret this as a string, so as text,
and so we need to also convert this to a number,
and so we use another built-in JavaScript function
which is called "parseInt," so this
is going to be converted to an integer.
Okay, and so now the answer will be a number.
So as long as the user enters one of the numbers of course.
If the user inputs text, then JavaScript will not be able
to convert it to a number, but we're just gonna suppose
that the user inputs a number here.
Okay, and what do we wanna do next?
We want to display this string here, so "Correct answer :D"
if the answer is true, or this string here,
so "Wrong, please try again!" if the answer is false.
So how can we do that?
We could of course go ahead and write an if-else statement
like we would have to do if we were storing
this data in an object, but we're not,
and so we can use, once again to our advantage,
the fact that we stored these two strings here
with the keys of true and false, so as Booleans.
So all we need to do is to retrieve this string
if the answer is correct, and retrieve
this string if the answer is incorrect.
So the first thing is to compare
the answer with the true answer, right?
So we say question.get('answer').
And so if the input is the same as the correct answer,
then this expression here will be true, right?
And if it's incorrect then of course it's false,
and now you can see once again the beauty
of using true-false as the keys,
because now all we have to do is to say question.get,
and then use this here as the key,
because this will either be true or false,
and so if it's true it's going to retrieve
the string for true, and if it's false
it's going to retrieve the string for false.
So this is very useful and very handy,
so we don't have to write an if-else statement here,
we can simply do it like this.
Okay, so let's now console.log this
so that we can actually see it as our output.
Okay, so let's load this and input the correct answer.
Let's say 4, and so "Wrong, please try again!"
So yeah, it's working.
Now if I say 3, which is the correct answer,
then we still get "Wrong" here, so something is not working.
Let's see, oh yeah, and that's because
we called it "correct" here, but then "answer" down here.
So of course need to be "correct,"
so that we read the correct value.
So let's try it again with number 4,
so it says "Wrong, please try again!"
And now at number 3, which is the correct answer,
and now it says "Correct answer :D,"
so yeah, this is really working.
So maybe this part here was a bit tricky,
and a little bit hard to get used to,
but I hope that you really understood it,
and if not then just pause the video,
and take a look at it again.
So now you probably wonder why maps are actually better
than objects to create hash maps, right?
And there are a couple of reasons.
So let's summarize what we learned in this lecture.
So the first reason why they're better is
because we can use anything as keys, which opens
a lot of possibilities as we just saw with this example.
And second, because maps are iterable,
and making it very easy to loop through them
and to manipulate data with them.
And reason number three is because it's really easy
to get the size of a map using the size property,
and that can also be very handy.
And finally, because we can easily add
and remove data from a map.
So all of these are strong arguments in choosing maps
over objects, if we wanna build hash maps.
All right, so I hope that all of this makes perfect sense
to you, and that you start using maps
if you choose to get started with ES6.
Okay, so see you soon.