class: center, middle # An Overview of `Map` and `Set` in JavaScript --- # About Me
### Mohsen Azimi #### Software Engineer @Apigee * Github: [`@mohsen1`](https://github.com/mohsen1) * Twitter: [`@mohsen____`](https://twitter.com/mohsen____) * Website: [`azimi.me`](http://azimi.me) --- # `Set` A set of values with **no repeated value**. --- # `Set` ### Making a `Set` object ```js var s = new Set(); s.add('London'); s.add('Los Angeles'); s.add('San Francisco'); s.add('London'); // silently ignores it s.size; // => 3 ``` --- # `Set` ### Comparison rules ```js var s = new Set([1, '1']); s.size; // => 2 s.has(1); // => true s.has('1'); // => true ``` --- # `Set` ### Comparison rules ```js var o1 = {}; var o2 = {}; var s = new Set(); s.add(o1); s.add(o2); s.size; // => 2 s.has(o1) // => true s.has(o2) // => true s.has({}) // => false ``` --- # `Set` ### Use case ```js var cities = [ { country: 'USA', name: 'San Francisco' }, { country: 'Canada', name: 'Toronto' }, { country: 'France', name: 'Paris' }, { country: 'USA', name: 'New York' } ]; ``` ```js var countries = []; cities.forEach(function (city) { if (countries.indexOf(city.country) === -1) { countries.push(city.country); } }); console.log('Countries are', countries.join(', ')); ``` --- # `Set` ### Use case ```js var cities = [ { country: 'USA', name: 'San Francisco' }, { country: 'Canada', name: 'Toronto' }, { country: 'France', name: 'Paris' }, { country: 'USA', name: 'New York' } ]; ``` ```js var countries = {}; cities.forEach(function (city) { // value is not important, we want fast lookups countries[city.country] = true; }); console.log('Countries are', Object.keys(countries).join(', ')); ``` --- # `Set` ### Use case ```js var cities = [ { country: 'USA', name: 'San Francisco' }, { country: 'Canada', name: 'Toronto' }, { country: 'France', name: 'Paris' }, { country: 'USA', name: 'New York' } ]; ``` ```js const countries = new Set(); cities.forEach( (city) => countries.add(city.country) ); console.log('Countries are', Array.from(countries).join(', ')); ``` --- # `Set` ### Use case ```js var cities = [ { country: 'USA', name: 'San Francisco' }, { country: 'Canada', name: 'Toronto' }, { country: 'France', name: 'Paris' }, { country: 'USA', name: 'New York' } ]; ``` ```js // Lets go fancy! const countries = new Set(cities.map((city) => city.country)); console.log('Countries are', Array.from(countries).join(', ')); ``` --- # `Set` ### Use case ```js function Country(name) { this.name = name; } var USA = new Country('USA'); var Canada = new Country('Canada'); var France = new Country('France'); var cities = [{ country: USA, name: 'San Francisco' }, { country: Canada, name: 'Toronto' }, { country: France, name: 'Paris' }, { country: USA, name: 'New York' }]; var countries = {}; cities.forEach(function (city) { // city.country.toString() => [object Object] countries[city.country] = true; }); ``` --- # `Set` ### Use case ```js class Country { constructor(name) { this.name = name; } } const USA = new Country('USA'); const Canada = new Country('Canada'); const France = new Country('France'); const cities = [{ country: USA, name: 'San Francisco' }, { country: Canada, name: 'Toronto' }, { country: France, name: 'Paris' }, { country: USA, name: 'New York' }]; const countries = new Set( cities.map((city) => city.country) ); ``` --- # `Map` A key-value hash that is **not limited to string keys** --- # `Map` ### Making a `Map` object ```js var m = new Map(); m.set('one', 1); m.set('two', 2); m.set('three', 3); m.has('three'); // => true m.get('two'); // => 2 m.size; // => 3 ``` --- # `Map` ### Making a `Map` object ```js var m = new Map([ ['key1', 'value'], ['key2', 'value2'] ]); ``` --- # `Map` ### Making a `Map` object ```es6 class Counter { *[Symbol.iterator]() { for (let i = 1; i <= 10; i++) yield [```key ${i}`, i]; // yielding an "entry" } } var s = new Counter(); var map = new Map(s); console.log(Array.from(map.keys())); // "key 1","key 2","key 3","key 4"... ``` --- # `Map` ### Use case ```es6 class Country { constructor(name) { this.name = name; } } const USA = new Country('USA'); const Canada = new Country('Canada'); const France = new Country('France'); const cities = [{ country: USA, name: 'San Francisco' }, { country: Canada, name: 'Toronto' }, { country: France, name: 'Paris' }, { country: USA, name: 'New York' }]; const countries = new Map(); cities.forEach((city)=> { if (map.has(city.country)) { map.set(city.country, new Set(city)); } else { map.get(city.country).add(city); } }); ``` --- # `Map` ### Use case ```js var person1 = new Person('Mark'); var person2 = new Person('Nancy'); var divs = new Map(); var selectedPeople = []; divs.set(document.querySelector('.person.one'), person1); divs.set(document.querySelector('.person.two'), person2); document.addEventListener('dragend', function (event) { selectedPeople.push(divs.get(event.srcElement)); }); ``` --- # Iterating in `Set` and `Map` ### Iterables * #### `Set` * #### `Map` * #### `{Map|Set}#keys()` * #### `{Map|Set}#values()` * #### `{Map|Set}#entries()` --- # Iterating in `Set` and `Map` ### `for..of` ```es6 const s = new Set([1, 2, 3]) for (let v of s) { console.log(v); } // => // 1 // 2 // 3 ``` --- # Iterating in `Set` and `Map` ### `for..of` ```js const m = new Map([ ['alpha', 1], ['beta', 2], ['gamma', 3] ]); for (let p of m) { console.log(p); } // => // ["alpha",1] // ["beta",2] // ["gamma",3] ``` --- # Iterating in `Set` and `Map` ### `for..of` ```js const m = new Map([ ['alpha', 1], ['beta', 2], ['gamma', 3] ]); for (let k of m.keys()) { console.log(k); // alpha beta gamma } for (let v of m.values()) { console.log(v); // 1 2 3 } for (let p of m.entries()) { console.log(p); // ["alpha",1] ["beta",2] ["gamma",3] } ``` --- # Iterating in `Set` and `Map` ### `for..of` ```js const s = new Set([1, 2, 3]); for (let k of s.keys()) { console.log(k); // 1 2 3 } for (let v of s.values()) { console.log(v); // 1 2 3 } for (let p of s.entries()) { console.log(p); // [1,1] [2,2] [3,3] } ``` --- # Iterating in `Set` and `Map` ### `forEach` ```es6 const s = new Set([1, 2, 3]); s.forEach((value, key, set)=> { console.log(value); // 1 2 3 }); ``` ```es6 const m = new Map([ [window, 'Window'], [document, 'Document'] ]); m.forEach((key, value, map)=> { console.log(```${key.toString()}#toString returns ${value}`); // Window#toString returns [object Window] // Document#toString returns [object HTMLDocument] }); ``` --- # Iterating in `Set` and `Map` ### `Array.from` ```js const m = new Map([ [window, 'Window'], [document, 'Document'] ]); Array.from(m); // => [ // [window, 'Window'], // [document, 'Document'] // ] ``` ```js const s = new Set(); s.add(1); a.add(2); Array.from(s); // => [1, 2] ``` --- # `WeakMap` and `WeakSet` * Only objects as keys * No strong reference to keys * No `size`, `keys` and `entries` --- # `WeakMap` and `WeakSet` ```es6 const s = new WeakSet(); const myObject = {value: {me: 1}}; s.add(myObject.value); delete myObject.value; ``` --- class: center, middle # Thank you! ### Questions?