In the previous chapter, we learned about sets. In this chapter, we will continue our discussion about data structures that store unique values (non-repeated values) using dictionaries and hashes.
Sets, dictionaries, and hashes store unique values. In a set, we are interested in the value itself as the primary element. In a dictionary (or map), we store values as pairs as [key, value]. The same goes for hashes (they store values as pairs as [key, value]); however, the way that we implement these data structures is a little bit different, as we will see in this chapter.
As you have learned, a set is a collection of distinct elements (non-repeated elements). A dictionary is used to store [key, value] pairs, where the key is used to find a particular element. The dictionary is very similar to a set; a set stores a [key, key] collection of elements, and a dictionary stores a [key, value] collection of elements. A dictionary is also known as a map.
In this chapter, we will cover some examples of the use of the dictionary data structure in the real world: a dictionary itself (the words and their definitions), and an address book.
Similar to the Set
class, ECMAScript 6 also contains an implementation of the Map
class—also known as a dictionary.
You can check out the details of the ECMAScript 6 Map
class implementation at https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map (or http://goo.gl/dm8VP6).
The class we are going to implement in this chapter is based on the Map
implementation of ECMAScript 6. You will notice that it is very similar to the Set
class (but instead of storing [key, key] pair, we will store [key, value] pair).
This is the skeleton of our Dictionary
class:
function Dictionary(){
var items = {};
}
Similar to the Set
class, we will also store the elements in an Object
instance instead of an array.
Next, we need to declare the methods available for a map/dictionary:
set(key,value)
: This adds a new item to the dictionary.remove(key)
: This removes the value from the dictionary using the key.has(key)
: This returns true
if the key exists in the dictionary and false
otherwise.get(key)
: This returns a specific value searched by the key.clear()
: This removes all the items from the dictionary.size()
: This returns how many elements the dictionary contains. It is similar to the length
property of the array.keys()
: This returns an array of all the keys the dictionary contains.values()
: This returns an array of all the values of the dictionary.The first method we will implement is the has(key)
method. We will implement this method first because it will be used in other methods such as set
and remove
. We can see its implementation in the following code:
this.has = function(key){ return key in items; };
The implementation is exactly the same as what we did for the Set
class. We are using the JavaScript in
operator to verify that the key
is a property of the items
object.
The next method is the set
method:
this.set = function(key, value){ items[key] = value; //{1} };
This receives a key
and a value
parameter. We simply set the value to the key
property of the items
object. This method can be used to add a new value or update an existing one.
Next, we will implement the remove
method. It is very similar to the remove
method from the Set
class; the only difference is that we first search for key
(instead of value
):
this.remove = function(key){ if (this.has(key)){ delete items[key]; return true; } return false; };
Then we use the JavaScript remove
operator to remove the key
attribute from the items
object.
If we want to search for a particular item from the dictionary and retrieve its value, we can use the following method:
this.get = function(key) { return this.has(key) ? items[key] : undefined; };
The get
method will first verify that the value that we would like to retrieve exists (by searching for key
), and if the result is positive, its value is returned, if not, an undefined
value is returned (remember that undefined
is different from null
—we covered this concept in Chapter 1, Javascript – A Quick Overview).
The next method is the values
method. This method will be used to retrieve an array of all values
instances present in the dictionary:
this.values = function(){ var values = []; for (var k in items) { //{1} if (this.has(k)) { values.push(items[k]); //{2} } } return values; };
First, we will iterate through all attributes from the items
object (line {1}
). Just to make sure the value exists, we will use the has
function to verify that key
really exists, and then we add its value to the values
array (line {2}
). At the end, we simply return all the values found.
We cannot simply use the for-in
statement and iterate through the properties of the items
object. We also need to use the has
method (to verify if the items
object has that property) because the object's prototype contains additional properties of the object as well (properties are inherited from the base JavaScript Object
class, but it still has properties of the object—which we are not interested in for this data structure).
The clear
, size
, and keys
methods are exactly the same from the Set
class. For this reason, we will not go through them again in this chapter.
Finally, just so that we can verify the output of the items
property, let's implement a method called getItems
that will return the items
variable:
this.getItems = function(){ return items; }
First, we create an instance of the Dictionary
class, and then we add three e-mails to it. We are going to use this dictionary
instance to exemplify an e-mail address book.
Let's execute some code using the class we created:
var dictionary = new Dictionary(); dictionary.set('Gandalf', '[email protected]'), dictionary.set('John', '[email protected]'), dictionary.set('Tyrion', '[email protected]'),
If we execute the following code, we will get the output as true
:
console.log(dictionary.has('Gandalf'));
The following code will output 3
because we added three elements to our dictionary instance:
console.log(dictionary.size());
Now, let's execute the following lines of code:
console.log(dictionary.keys()); console.log(dictionary.values()); console.log(dictionary.get('Tyrion'));
The output will be as follows, in the respective order:
["Gandalf", "John", "Tyrion"] ["[email protected]", "[email protected]", "[email protected]"] [email protected]
Finally, let's execute some more lines of code:
dictionary.remove('John'),
Let's also execute the following ones:
console.log(dictionary.keys()); console.log(dictionary.values()); console.log(dictionary.getItems());
The output will be as follows:
["Gandalf", "Tyrion"] ["[email protected]", "[email protected]"] Object {Gandalf: "[email protected]", Tyrion: "[email protected]"}
As we removed one element, the dictionary
instance now contains only two elements. The highlighted line exemplifies how the items
object is structured internally.