Your Web News in One Place

Help Webnuz

Referal links:

Sign up for GreenGeeks web hosting
January 21, 2023 09:51 am GMT

5 Reasons To Choose JavaScript Maps Over Objects For Storing Key-Value Pairs(With Examples)

At 18 I started my "career" as an IT support guy.
At 20 I was flying 80 hours per month as a flight attendant.
At 22 I got my commercial airplane pilot license.
At 29 I was a carpenter and today at 32 I work as a software developer.

If there's one thing I know how to do well, it is how to keep up with changes. Because if you don't, you are left behind. I know firsthand how comfortable it is to use stuff you know by heart instead of giving the 'new' a try.

But discomfort is what makes you grow, as a human and as a dev.

Let's dive head first and see what the "newish" Map can teach us today.

What is the Map object?

Here's the holy source's (MDN) definition:

The Map object holds key-value pairs and remembers the original insertion order of the keys. Any value (both objects and primitive values) may be used as either a key or a value.

To put it simply, Map is JavaScript's native hash or dictionary data structure.

Syntax: Map vs Object

Here's a handy cheat sheet that does a great job at showing their syntax differences, posted by Andrej on Twitter.

Image description

He also recorded performance tests if you are interested.

Reason 1: You Won't Overwrite Default Keys By Accident

Map
By default, a Map does not contain any keys. It is a clean slate. It only has what you put into it.

Neither more nor less.

Image description

Object
Objects by default have their prototype, so it contains default keys that could potentially clash with your own keys.

This can be bypassed by passing null as the prototype when creating a new Object: Object.create(null)

Check out the difference:

  • New Object

Image description

  • New Object with null prototype

Image description

Reason 2: It Accepts Any Type As Key

Map
Maps accept any type of key. That includes functions, objects, and all primitives(string, number, boolean, symbol, undefined, null, and bigint).

let obj = { 'a': 'a' };let func = () => 'hey';//you can also initialize multiple values at once using array syntaxlet map = new Map([[123, true], [true, 123], [obj, 'object'], [func, 'function']])map.keys() // 123, true, Object, () => 'hey'map.get(obj) // 'object'map.get(func) // 'function'map.get({ 'a': 'a' }) // undefined //Object and Functions are stored by reference, so { 'a':'a' } and obj are different objects)

Object
Object's key must be either a String or a Symbol.

let obj1 = { 'a': 'a' };let func = () => 'hey';let obj = { 123: true, true: 123, obj1: 'object', func: 'function' };Object.keys(obj) // ['123', 'true', 'obj1', 'func'] converts all keys to stringsobj[func] //undefinedobj['func'] // 'function'

Reason 3: Maps Are Iterable

Map
Maps are natively iterable. That means you can loop over them with for of or .forEach() loops.

const map = new Map();map.set(0, 'zero').set(1, 'one'); //you can chain .set()for (const [key, value] of map) {  console.log(`key: ${key}, value: ${value}`);}// key: 0, value: zero// key: 1, value: one//if you just want the 'values' or just the 'keys'for (const key of map.keys()) { // or map.values()  console.log(key);}// 0// 1map.forEach((value, key) => console.log(`key: ${key}, value: ${value}`));// key: 0, value: zero// key: 1, value: one

Object
Objects are not iterable, even though you can iterate over them using for in and Object.Entries()

let obj = { 0: 'zero', 1: 'one' }for(let key in obj){    console.log(`key: ${key}, value: ${obj[key]}`)}// key: 0, value: zero// key: 1, value: oneObject.entries(obj).forEach((item) => console.log(`key: ${item[0]}, value: ${item[1]}`))// key: 0, value: zero// key: 1, value: one

Reason 4: Maps Can Be Merged With Arrays, And Converted To Arrays

Map
Maps are Arrays are 100% compatible, making it intuitive move from one to another.

Here's how you can convert a Map into an Array

let map = new Map([ [1, 'one'], [2, 'two'] ]);Array.from(map) //[ [1, 'one'], [2, 'two'] ] exactly the same array you initially passed in//or you can use the spread operatorconst newArr = [...map];

An Array into a Map

let arr = [ [1, 'one'], [2, 'two'] ];new Map(arr); //{ 1 => 'one', 2 => 'two' }

Here's how you can merge a Map and an Array

let map = new Map([ [1, 'one'], [2, 'two'] ]);let arr = [3, 'three']let combinedMap = new Map(...map, arr); // { 1 => 'one', 2 => 'two', 3 => 'three' }let combinedArr = [...map, arr];// [ [1, 'one'], [2, 'two'], [3, 'three'] ]

Object
Concerting an Object into an Array

let obj = { 1: 'one', 2: 'two'};Array.from(obj) // [] doesn't work//you'd have to doArray.from(Object.entries(obj))//[ ['1', 'one'],['2', 'two'] ]//or[...Object.entries(obj)]//[ ['1', 'one'],['2', 'two'] ]

Reason 5: You Can Easily Check The Size

Map
Map has a built-in size property that returns its size.

let map = new Map([1, 'one'], [true, 'true']);map.size // 2

Object
To check the size of an object you have to combine Object.keys() with .length

let obj = { 1: 'one', true: 'true' };Object.keys(obj).length // 2

The downside? No Native Method For Serialization And Parsing

Map
Maps have no native support for serialization or parsing to and from JSON.

The documentation suggests implementing your own by using the replacer argument that can be passed to JSON.stringify(obj, replacer) and the reviver argument passed to JSON.parse(string, reviver)

You can find the suggested implementation here

Object
You can natively serialize and parse an Object to and from JSON using JSON.stringify() and JSON.parse() respectfully.

2 Examples of how you can replace Object with Map

#1 Calculating the total price and items of an eCommerce shopping cart

This is one of the examples from the Complete Guide To JavaScript .reduce() Function

Given the following array

const shoppintCart = [  { price: 10, amount: 1 },  { price: 15, amount: 3 },  { price: 20, amount: 2 },]

We want to return an Object like { totalItems: 6, totalPrice: 45 }

This is the original code

shoppintCart.reduce(  (accumulator, currentItem) => {    return {      totalItems: accumulator.totalItems + currentItem.amount,      totalPrice:        accumulator.totalPrice + currentItem.amount * currentItem.price,    }  },  { totalItems: 0, totalPrice: 0 } //initial value object)// { totalItems: 6, totalPrice: 45 }

This is a version using Map

shoppintCart.reduce(  (accumulator, currentItem) => {      accumulator.set('totalItems', accumulator.get('totalItems') + currentItem.amount);      accumulator.set('totalPrice', accumulator.get('totalPrice') + currentItem.price);      return accumulator;  },  new Map([['totalItems', 0], ['totalPrice', 0]]))// { 'totalItems' => 6, 'totalPrice' => 45 }

#2 A Different Way To Remove Duplicate Objects From An Array

This is a piece of code I actually used in the bookshelf app I made when I started learning JavaScript.

Googling about how to remove duplicate objects from an array led me to the example I share below.

This is an array with one duplicate object

const books = [  { id: 1, title: 'How To Win Friends And Influence People', author: 'Dale Carnegie' },  { id: 1, title: 'How To Win Friends And Influence People', author: 'Dale Carnegie' },  { id: 2, title: 'The Alchemist', author: 'Paulo Coelho' },]

Here's a peculiar way to remove the duplicate:

const uniqueObjsArr = [   ...new Map(books.map(book => [book.id, book])).values()];

There is a bit too much happening on the above one-liner.
Let's break it down into chunks so it is easy to digest.

// 1. map the array into an array of arrays with `id` and `book`const arrayOfArrays = books.map(book => [ book.id, book ])// arrayOfArrays:/*[    [ 1, {id: 1, title: 'How To Win Friends And Influence People', author: 'Dale Carnegie' } ],   [ 1, {id: 1, title: 'How To Win Friends And Influence People', author: 'Dale Carnegie' } ],   [ 2, { title: 'Alchemist', author: 'Paulo Coelho' } ]]*/// 2. The duplicate is automatically removed as keys have to be uniqueconst mapOfUniqueObjects = new Map(arrayOfArrays)// mapOfUniqueObjects: /*{   1 => {id: 1, title: 'How To Win Friends And Influence People', author: 'Dale Carnegie'},   2 => { title: 'Alchemist', author: 'Paulo Coelho' }}*/// 3. Convert the values back into an array.const finalResult = [...mapOfUniqueObjects.values()];// finalResult:/*[   {id: 1, title: 'How To Win Friends And Influence People', author: 'Dale Carnegie'},   {id: 2, title: 'The Alchemist', author: 'Paulo Coelho'}]*/

Conclusion

If you need to store key-value pairs(hash or dictionary) use Map.

If you're only using string-based keys and need maximum read performance, then objects might be a better choice.

Other than that, use whatever you want because, at the end of the day, this is just a blog post of a random dude on the internet Lol.

Here's what we covered:

  • What is the Map object?
  • Syntax: Map vs Object
  • Reason 1: You Won't Overwrite Default Keys By Accident
  • Reason 2: It Accepts Any Type As Key
  • Reason 3: Maps Are Iterable
  • Reason 4: Maps Can Be Merged With Arrays, And Converted To Arrays
  • Reason 5: You Can Easily Check The Size
  • The downside? No Native Method For Serialization And Parsing
  • 2 Examples of how you can replace Object with Map

Thanks for reading!

If you like this article:

*Leave a comment below(You can just say hi!)
*Follow me on Twitter@theguspear

Catch you later,

Gus.


Original Link: https://dev.to/gustavupp/5-reasons-to-choose-javascript-maps-over-objects-for-storing-key-value-pairswith-examples-39dd

Share this article:    Share on Facebook
View Full Article

Dev To

An online community for sharing and discovering great ideas, having debates, and making friends

More About this Source Visit Dev To