Exploring ES6: Sets and Maps
Tags: javascript, beginners, es6
Published: 2022-12-05 00:56:40

So, in _javascript_ everything _is_ an Object right? Well, here are some more Objects with extended functionality, courtesy of ECMAScript 6.
Continuing, I will list what Sets and Maps provide us and try to make a couple small cases for why we would use either or both!

A quick preface from our favorite, MDN, describes a difference for Sets in comparison of the `Set.has` method and the `Array.prototype.includes` method and expresses that `.has` is faster "when an Array object has a length equal to a Set object's size."*

MDN also describes Maps advantages over Objects as thus: "A Map does not contain any keys by default. It only contains what is explicitly put into it" whereas the Object.prototype could result in "key collision" in some unfortunate cases.*

*See Works Cited for MDN references

I will cover the above mentioned methods, properties, and functionalities of Maps and Sets as follows:

## SETS
Sets are collection objects with built in methods. They act similar to arrays in that they store values in order but they cannot be accessed in the same 0-index way.
`mySet[0] // --> undefined`
Values in a set are assigned value, value as their key, value pair correspondence. They will be stored in order of insertion.
What makes Sets interesting is that each value stored in a Set _**must**_ be _**unique**_.

## Set Methods:

1. `.add(value) - adds to end like .push`
2. `.has(value) - will return true or false if the Set contains the value we are looking for` 
3. `.values() - will return an iterable of values in the Set`
4. `.entries() - will return an iterable of [value, value] pairs for every value in the Set`
5. `.delete(value) - will delete the value, value pair in the Set and return a Boolean value on success or failure.`
6. `.clear() - will empty the Set `
7. `.forEach(cb) - built in .forEach method which can receive a callback function`
8. `.size - a property of a Set that will return a number representing the size of stored items upon reference`

## WHY?
Why make something sweet and simple like the Array a weird object like a Set? Well, one trick I really like is using the Set for DE-duping. If you have an array full of pesky duplicates you can pass that array as an argument to a Set with the 'new' keyword and voila! Now only unique values remain. 
```javascript
let myArray = [1, 2, 3, 4, 5, 5, 3]; // --> [1, 2, 3, 4, 5, 5, 3]
let mySet = new Set(myArray);        // --> Set(5) {1, 2, 3, 4, 5}
let unique = [ ...mySet ];           // --> [1, 2, 3, 4, 5]
```
In the example above we use the spread operator to pass our Set back into an array for easy duplicate removal and conversion back from Set to Array.
```javascript
// long array full of duplicates
let myArray = [1, 2, 1, 3, 1, 2, 4,
               5, 5, 4, 2, 1, 3, 2,
               1, 3, 4, 4, 5, 1, 2, 
               1, 5, 5, 1, 2, 1, 3];

// new empty Set
let mySet = new Set();
```
Suppose you know ahead of time that you will need a collection of unique values, collect in a Set:
```javascript
// forEach duplicates array, set.add method to populate...
myArray.forEach(el => mySet.add(el));

// output --> Set(5) {1, 2, 3, 4, 5}
// so clean!! :]
```


## MAPS

Maps are collection objects that store key, value pairs (like Objects). They differ in that a Maps keys can be _any_ value, including functions or objects.

##Map Methods:

1. `.set(key, value) - adds next key and value pair to Map`
2. `.get(key) - will return the value connected to the target key`
3. `.has(key) - will return a Boolean if Map contains target key`
4. `.keys() - will return an iterable of keys in the Map`
5. `.values() - just like keys but for values`
6. `.entries() - returns an iterable of key, value pairs for every entry in the Map, it looks like this:`
`[Map Entries] { [ {}, 'a' ], [ [], 'b' ], [ 1, 1 ], [ 2, 'two' ] }`
7. `.delete(key) - just like the delete keyword for Objects it will delete the key, value pair at the target key`
8. `.clear() - will empty the entire Map`
9. `.forEach() - built in .forEach, it explains itself...`
10. `.size - actually invokes getSize. This is my favorite feature because it effectively acts as Array.length but for something resembling an Object. It will return a number but doesn't need parens() to invoke.`

## WHY?
You're probably thinking, "cool, colin... thanks for taking something simple and making it confusing..." BUT, a collection like a Map will provide us extra functionality and in the right scenarios afford us an advantage, and as programmers we have a toolbelt of tactics and advantages so here is a scenario I find Maps to be beneficial...
```javascript
const myObject = {};     // --> {}
const myMap = new Map(); // --> Map(0) {}

const a = {};
const b = {};
```
Do you have any predictions of what will happen if we try to assign these empty objects as properties to an Object? What if we assign them to a Map?

```javascript
myObject[a] = 'a'; // --> { '[object Object]': 'a' }
myObject[b] = 'b'  // --> { '[object Object]': 'b' }

myMap.set(a, 'a'); // --> Map(1) { {} => 'a' }
myMap.set(b, 'b'); // --> Map(2) { {} => 'a', {} => 'b' }
```
The output on the right represents `console.log(myObject)` and `console.log(myMap)` respectively. As you can see, the Object assignment assumes our variables to be the same object and therefore overwrites the '[object Object]' property. With our Map, because each Key _has_ to be unique, it knows to store these variables independently. The same thing would happen if we were using empty Arrays: `a = [] and b = []` so Maps are good to store empty collections that we may populate later. 

Thanks for reading my blog! I love the syntax _sugar_ that is ES6 and the little tricks that they provide. As I discover more I will continue to catalogue them here. Happy coding!

## WORKS CITED

(MDN)
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map