Introduction Object Set And Map.
- The Set object allows you to store values that are unique
- The Map object allows you to store key-value pairs and remember the initial insertion order of the keys.
Set
Set Is a collection of values. You can iterate through Set elements in the order of insertion. The value in Set can only be a unique set of Sets. In Javascript, the Set object allows customization, providing useful methods such as adding, modifying, and iterating over the elements of the Set collection.
Array vs Set
Array, like a collection, is a data structure that allows to calculate, remove and iterate over its indexes. However, an Array differs from a Set in the sense that it allows the addition of duplicate values and its operations are relatively slower.
Example: When searching through an array with linear time complexity of O (n), it’s like inserting an element in the middle of an array. This means that the runtime for searching and inserting indexes for the array increases as the size of the array increases.The Push and Pop array methods have a runtime of O (1), meaning: This operation will have a constant execution time regardless of the aray size increasing n.
In practice, however, the Push (O) operation incurs a copy cost when new adjacent memory locations are allocated to the newly created array array.
Set has run time of O (1) with all calculations and searches.
Creating a Set
1 2 3 4 | const set = new Set(); console.log(set); // Set {} |
Initializing a Set
To initialize a Set, we can pass an array of values to the Set constructor, which will create a Set with those values:
1 2 3 4 5 6 | const confectioneries = new Set(['oreo', 'marshmallow','oreo', 'kitkat', 'gingerbread']); console.log(confectioneries); // result: Set { 'oreo', 'marshmallow', 'kitkat', 'gingerbread' } |
In the above paragraph, the oreo duplicate value, is quietly deleted from Set and only the unique values are returned.
Adding Items
We can add more items to the Set using the add()
. This method adds a new value to the Set object and returns Set.
Adding a duplicate entry to the Set object will not return an error, instead, that item will not be added.
1 2 3 4 5 6 7 8 9 10 11 12 | const confectioneries = new Set(['oreo', 'marshmallow', 'kitkat', 'oreo','gingerbread']); confectioneries.add('donut'); console.log(confectioneries); //_ log result: Set { 'oreo', 'marshmallow', 'kitkat', 'gingerbread', 'donut' } _ confectioneries.add('kitkat'); console.log(confectioneries); //_ log result: Set { 'oreo', 'marshmallow', 'kitkat', 'gingerbread', 'donut' } _ |
Deleting Items
Use the delete()
, to delete the value to delete. The method will return a true
Boolean value if the delete succeeds and false
if it fails.
We can delete all Set elements with the clear () method.
1 2 3 4 5 6 7 8 9 10 | confectioneries.delete('kitkat'); console.log(confectioneries); //_ log result: Set { 'oreo', 'marshmallow', 'gingerbread', 'donut' }_ confectioneries.clear(); console.log(confectioneries); // log result: Set {} |
Size of a Set
We can get the size of the Set using the size attribute on the Set prototype. This is similar to the length attribute for arrays:
1 2 3 4 | const confectioneries = new Set(['oreo', 'marshmallow', 'kitkat', 'oreo','gingerbread']); console.log(confectioneries.size); // log result: 5 |
Searching for Items
We need to know there is a specific element in Set. This can be done using the has()
.
The has()
returns true
if the element is in Set and false
if it is not:
1 2 3 | console.log(confectioneries.has('marshmallow')); // log result: true |
Returning the Items in a Set
We can return items in a Set in the same order of insertion using the values()
. This method returns a new setIterator object.
A similar method to return items in a collection is the keys()
:
1 2 3 4 5 | console.log(confectioneries.values()); // _log result: _[_Set Iterator] { 'oreo', 'marshmallow', 'kitkat', 'gingerbread', 'donut' }_ console.log(confectioneries.keys()); //_ log result: _[_Set Iterator] { 'oreo', 'marshmallow', 'kitkat', 'gingerbread', 'donut' }_ |
The setIterator object is an Iterator object because it implements Iterizable and Iterator protocols. The Iterable protocol specifies an iteration through the values of using loop structures.
It also makes the values repeated by the next()
. When we call next()
on a setIterator object, we will get the next value in the iteration and false until all Set values have been repeated:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | let iterator = confectioneries.values(); console.log( iterator.next()); // _{ value: 'oreo', done: false } _ console.log( iterator.next()); // _{ value: 'marshmallow', done: false } _ console.log( iterator.next()); //_ { value: 'kitkat', done: false } _ console.log( iterator.next()); //_ { value: 'gingerbread', done: false } _ console.log( iterator.next()); //_ { value: 'donut', done: false } _ console.log( iterator.next()); // _{ value: undefined, done: true }_ |
Because the Department implements the Iterable protocol, loop structures like for … of can be used as shown below:
1 2 3 4 5 6 7 8 9 10 11 12 13 | for (let confectionery of confectioneries) { console.log(confectionery); } /_ _console.log() result oreo marshmallow kitkat gingerbread donut __/ |
WeakSets
WeakSets provide additional flexibility when working with data structures. They differ from normal data sets in that they only accept objects and cannot be repeated; they can be repeated and there is no clear () method. To fix this we will use WeakSets. We can create a Weakset using the Weakset constructor:
1 2 3 4 5 6 | let user1 = {name: 'user 1', email: ' <a class="__cf_email__" href="/cdn-cgi/l/email-protection" data-cfemail="fc898f998ecdbc99849d918c9099d29f9391">[email protected]</a> '}; let user2 = {name: 'user 2', email: ' <a class="__cf_email__" href="/cdn-cgi/l/email-protection" data-cfemail="087d7b6d7a3a486d70696578646d266b6765">[email protected]</a> '}; let user3 = {name: 'user 3', email: ' <a class="__cf_email__" href="/cdn-cgi/l/email-protection" data-cfemail="25505640571665405d44485549400b464a48">[email protected]</a> '}; const users = new WeakSet([user1, user2, user3]); |
Maps
Maps in JavaScript are objects designed to effectively store and retrieve items based on a unique key for each element. Maps store key-value pairs in which both the key and value can be primitive or other objects or both.
A Map object repeats its elements in the order in which they are inserted – a for … of that returns an array [key, value]
for each iteration.
Creating a Map
1 2 3 4 | const users = new Map(); console.log(users); // Map {} |
Adding Items
Key-value pairs are added to the Map using the set()
. This method has two arguments, first a key
and second value
, referenced by the key
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | users.set('John Doe', { email: ' <a class="__cf_email__" href="/cdn-cgi/l/email-protection" data-cfemail="d3b9bcbbbdb7bcb693b6abb2bea3bfb6fdb0bcbe">[email protected]</a> ', }); users.set('Jane Doe', { email: ' <a class="__cf_email__" href="/cdn-cgi/l/email-protection" data-cfemail="741e151a11101b1134110c15190418115a171b19">[email protected]</a> ', }); console.log(users); /__ console.log result Map { 'John Doe' => { email: ' <a class="__cf_email__" href="/cdn-cgi/l/email-protection" data-cfemail="0d676265636962684d68756c607d6168236e6260">[email protected]</a> '}, 'Jane Doe' => { email: ' <a class="__cf_email__" href="/cdn-cgi/l/email-protection" data-cfemail="d0bab1beb5b4bfb590b5a8b1bda0bcb5feb3bfbd">[email protected]</a> '} } __/ |
Unlike Set, which removes duplicate keys, Maps will update the value attached to that key:
1 2 3 4 5 6 7 8 9 10 11 12 | users.set('John Doe', { email: ' <a class="__cf_email__" href="/cdn-cgi/l/email-protection" data-cfemail="365c595e5852595302010176534e575b465a531855595b">[email protected]</a> ', }); console.log(users); /__ console.log result Map { 'John Doe' => {email: ' <a class="__cf_email__" href="/cdn-cgi/l/email-protection" data-cfemail="2e444146404a414b1a19196e4b564f435e424b004d4143">[email protected]</a> '}, 'Jane Doe' => { email: ' <a class="__cf_email__" href="/cdn-cgi/l/email-protection" data-cfemail="9af0fbf4fffef5ffdaffe2fbf7eaf6ffb4f9f5f7">[email protected]</a> '} } __/ |
Deleting Items
Just like Set, key-value pairs can be deleted by the delete()
. The key to be deleted is passed to the () method as shown below:
1 2 | users.delete('Jane Doe'); |
The map also has a clear()
to remove all key-value pairs from the Map:
1 2 3 4 | users.clear(); console.log(users); // Map {} |
Searching for Items
Maps also has has()
to check if the key exists in Map or not. This method will return true if the key is in Map and false if it is not:
1 2 3 4 5 6 7 8 9 10 11 12 | let users = new Map(); users.set('John Doe', { email: ' <a class="__cf_email__" href="/cdn-cgi/l/email-protection" data-cfemail="bed4d1d6d0dad1dbfedbc6dfd3ced2db90ddd1d3">[email protected]</a> ', }); users.set('Jane Doe', { email: ' <a class="__cf_email__" href="/cdn-cgi/l/email-protection" data-cfemail="abc1cac5cecfc4ceebced3cac6dbc7ce85c8c4c6">[email protected]</a> ', }); console.log(users.has('John Doe')); // true |
Returning the Value of a Map item
The value of the key in the Map object can be received by the get()
on the Map prototype:
1 2 | console.log(users.get('Jane Doe'); // { email: ' <a class="__cf_email__" href="/cdn-cgi/l/email-protection" data-cfemail="ec868d8289888389ac89948d819c8089c28f8381">[email protected]</a> ' } |
It is possible to retrieve all keys and values of a Map object using the keys()
and values()
methods, respectively. These methods return a new MapIterator object with the next()
that can be used to iterate over Map items:
1 2 3 4 5 6 7 8 | let userKeys = users.keys(); console.log(userKeys.next()); // { value: 'John Doe', done: false } let userValues = users.values(); console.log(userValues.next()); // _{ value: { email: ' <a class="__cf_email__" href="/cdn-cgi/l/email-protection" data-cfemail="d7bdb8bfb9b3b8b297b2afb6baa7bbb2f9b4b8ba">[email protected]</a> ' }, done: false }_ |
As with Set, loop constructs such as for ... of
and forEach()
can be used to loop through Map:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | for (let user of users) { console.log('[for...of]: ', user); } /_ Log result _[_for...of]: _[_ 'John Doe', { email: ' <a class="__cf_email__" href="/cdn-cgi/l/email-protection" data-cfemail="254f4a4d4b414a4065405d44485549400b464a48">[email protected]</a> ' } ] _[_for...of]: _[___ 'Jane Doe', { email: ' <a class="__cf_email__" href="/cdn-cgi/l/email-protection" data-cfemail="a4cec5cac1c0cbc1e4c1dcc5c9d4c8c18ac7cbc9">[email protected]</a> ' } ] _/ users.forEach((value, key) => console.log('[__forEach()]: ', key, value)); /*_ Log result [__forEach()]: John Doe { email: ' <a class="__cf_email__" href="/cdn-cgi/l/email-protection" data-cfemail="a5cfcacdcbc1cac0e5c0ddc4c8d5c9c08bc6cac8">[email protected]</a> ' } _[_forEach()]: Jane Doe { email: ' <a class="__cf_email__" href="/cdn-cgi/l/email-protection" data-cfemail="1a707b747f7e757f5a7f627b776a767f34797577">[email protected]</a> ' } *_/ |
WeakMaps
As with WeakSets, WeakMaps is different from regular Map objects. WeakMaps only accepts objects as keys, cannot be repeated and has no clear()
.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | let users = new WeakMap(); const user1 = { name: 'John Doe', }; const user2 = { name: 'Jane Doe', }; users.set(user1, { email: ' <a class="__cf_email__" href="/cdn-cgi/l/email-protection" data-cfemail="1b717473757f747e5b7e637a766b777e35787476">[email protected]</a> ', }); users.set(user2, { email: ' <a class="__cf_email__" href="/cdn-cgi/l/email-protection" data-cfemail="741e151a11101b1134110c15190418115a171b19">[email protected]</a> ', }); |
As with WeakSets, setting the WeakMap object’s key to null will implicitly collect that index:
1 2 | user1 = null; |
Summary
In this article we have learned about Set and Map and their usage. This utility provides an easier and more efficient way to structure and access data in certain use cases.
References
https://scotch.io/tutorials/exploring-sets-and-maps-in-javascript https://javascript.info/map-set https://en.wikipedia.org/wiki/JavaScript
My article is over See you in the following articles: