Въведение
В JavaScript objects
се използват за съхраняване на множество стойности като сложна структура от данни.
Създава се обект с фигурни скоби {…}
и списък със свойства. Свойството е двойка ключ-стойност, където key
трябва да е низ и value
може да бъде от всякакъв тип.
От друга страна, arrays
са подредени колекция, която може да съхранява данни от всякакъв тип. В JavaScript масивите се създават с квадратни скоби [...]
и позволяват дублиращи се елементи.
До ES6 (ECMAScript 2015) JavaScript objects
и arrays
бяха най-важните структури от данни за обработка на колекции от данни. Общността на разработчиците нямаше много възможности за избор извън това. Въпреки това комбинация от обекти и масиви успя да обработи данни в много сценарии.
Имаше обаче няколко недостатъка,
- Обектните ключове могат да бъдат само от тип
string
. - Обектите не поддържат реда на вмъкнатите в тях елементи.
- Обектите нямат някои полезни методи, което ги прави трудни за използване в някои ситуации. Например не можете лесно да изчислите размера (
length
) на обект. Освен това изброяването на обект не е толкова лесно. - Масивите са колекции от елементи, които позволяват дубликати. Поддържането на масиви, които имат само различни елементи, изисква допълнителна логика и код.
С въвеждането на ES6 получихме две нови структури от данни, които адресират недостатъците, споменати по-горе, Map
и Set
. В тази статия ще разгледаме и двете отблизо и ще разберем как да ги използваме в различни ситуации.
Карта
Map
е колекция от двойки ключ-стойност, където ключът може да бъде от всякакъв тип. Map
запомня първоначалния ред на вмъкване на неговите елементи, което означава, че данните могат да бъдат извлечени в същия ред, в който са били вмъкнати.
С други думи, Map
има характеристики на двете Object
и Array
:
- Подобно на обект, той поддържа структура двойка ключ-стойност.
- Подобно на масив, той помни реда за вмъкване.
Как да създадете и инициализирате карта
Може Map
да се създаде нов по този начин:
const map = new Map();
Което връща празно Map
:
Map(0) {}
Друг начин за създаване на Map
е с начални стойности. Ето как да създадете a Map
с три двойки ключ-стойност:
const freeCodeCampBlog = new Map([ ['name', 'freeCodeCamp'], ['type', 'blog'], ['writer', 'Tapas Adhikary'], ]);
Което връща a Map
с три елемента:
Map(3) {"name" => "freeCodeCamp", "type" => "blog", "writer" => "Tapas Adhikary"}
Как да добавяте стойности към карта
За да добавите стойност към карта, използвайте set(key, value)
метода.
В set(key, value)
метода се два параметъра, key
и value
, където ключа и стойността може да бъде от всякакъв вид, примитивен ( boolean
, string
, number
и т.н.) или обект:
// create a map const map = new Map(); // Add values to the map map.set('name', 'freeCodeCamp'); map.set('type', 'blog'); map.set('writer', 'Tapas Adhikary');
Изход:
Map(3) {"name" => "freeCodeCamp", "type" => "blog", "writer" => "Tapas Adhikary"}
Моля, обърнете внимание, ако използвате един и същ ключ, за да добавите стойност към Map
няколко пъти, той винаги ще замени предишната стойност:
// Add a different writer map.set('writer', 'Someone else!');
Така че изходът ще бъде:
Map(3) {"name" => "freeCodeCamp", "type" => "blog", "writer" => "Someone else!"}
Как да получите стойности от карта
За да получите стойност от a Map
, използвайте get(key)
метода:
map.get('name'); // returns freeCodeCamp
Всичко за клавишите на картата
Map
keys can be of any type, a primitive, or an object. This is one of the major differences between Map
and regular JavaScript objects where the key can only be a string:
// create a Map const funMap = new Map(); funMap.set(360, 'My House Number'); // number as key funMap.set(true, 'I write blogs!'); // boolean as key let obj = {'name': 'tapas'} funMap.set(obj, true); // object as key console.log(funMap);
Here is the output:
Map(3) { 360 => "My House Number", true => "I write blogs!", {…} => true }
A regular JavaScript object always treats the key as a string. Even when you pass it a primitive or object, it internally converts the key into a string:
// Create an empty object const funObj = {}; // add a property. Note, passing the key as a number. funObj[360] = 'My House Number'; // It returns true because the number 360 got converted into the string '360' internally! console.log(funObj[360] === funObj['360']);
Map Properties and Methods
JavaScript's Map
has in-built properties and methods that makes it easy to use. Here are some of the common ones:
- Use the
size
property to know how many elements are in aMap
:
console.log('size of the map is', map.size);
- Search an element with the
has(key)
method:
// returns true, if map has an element with the key, 'John' console.log(map.has('John')); // returns false, if map doesn't have an element with the key, 'Tapas' console.log(map.has('Tapas'));
- Remove an element with the
delete(key)
method:
map.delete('Sam'); // removes the element with key, 'Sam'.
- Use the
clear()
method to remove all the elements from theMap
at once:
// Clear the map by removing all the elements map.clear(); map.size // It will return, 0
MapIterator: keys(), values(), and entries()
The methods keys()
, values()
and entries()
methods return a MapIterator
, which is excellent because you can use a for-of
or forEach
loop directly on it.
First, create a simple Map
:
const ageMap = new Map([ ['Jack', 20], ['Alan', 34], ['Bill', 10], ['Sam', 9] ]);
- Get all the keys:
console.log(ageMap.keys()); // Output: // MapIterator {"Jack", "Alan", "Bill", "Sam"}
- Get all the values:
console.log(ageMap.values()); // Output // MapIterator {20, 34, 10, 9}
- Get all the entries (key-value pairs):
console.log(ageMap.entries()); // Output // MapIterator {"Jack" => 20, "Alan" => 34, "Bill" => 10, "Sam" => 9}
How to Iterate Over a Map
You can use either the forEach
or for-of
loop to iterate over a Map
:
// with forEach ageMap.forEach((value, key) => { console.log(`${key} is ${value} years old!`); }); // with for-of for(const [key, value] of ageMap) { console.log(`${key} is ${value} years old!`); }
The output is going to be the same in both cases:
Jack is 20 years old! Alan is 34 years old! Bill is 10 years old! Sam is 9 years old!
How to Convert an Object into a Map
You may encounter a situation where you need to convert an object
to a Map
-like structure. You can use the method, entries
of Object
to do that:
const address = { 'Tapas': 'Bangalore', 'James': 'Huston', 'Selva': 'Srilanka' }; const addressMap = new Map(Object.entries(address));
How to Convert a Map into an Object
If you want to do the reverse, you can use the fromEntries
method:
Object.fromEntries(map)
How to Convert a Map into an Array
There are a couple of ways to convert a map into an array:
- Using
Array.from(map)
:
const map = new Map(); map.set('milk', 200); map.set("tea", 300); map.set('coffee', 500); console.log(Array.from(map));
- Using the spread operator:
console.log([...map]);
Map vs. Object: When should you use them?
Map
has characteristics of both object
and array
. However, Map
is more like an object
than array
due to the nature of storing data in the key-value
format.
The similarity with objects ends here though. As you've seen, Map
is different in a lot of ways. So, which one should you use, and when? How do you decide?
Use Map
when:
- Your needs are not that simple. You may want to create keys that are non-strings. Storing an object as a key is a very powerful approach.
Map
gives you this ability by default. - You need a data structure where elements can be ordered. Regular objects do not maintain the order of their entries.
- You are looking for flexibility without relying on an external library like
lodash
. You may end up using a library likelodash
because we do not find methods likehas()
,values()
,delete()
, or a property likesize
with a regular object.Map
makes this easy for you by providing all these methods by default.
Use an object when:
- You do not have any of the needs listed above.
- You rely on
JSON.parse()
as aMap
cannot be parsed with it.
Set
A Set
is a collection of unique elements that can be of any type. Set
is also an ordered collection of elements, which means that elements will be retrieved in the same order that they were inserted in.
A Set
in JavaScript behaves the same way as a mathematical set.
How to Create and Initialize a Set
A new Set
can be created like this:
const set = new Set(); console.log(set);
And the output will be an empty Set
:
Set(0) {}
Here's how to create a Set
with some initial values:
const fruteSet = new Set(['?', '?', '?', '?']); console.log(fruteSet);
Output:
Set(4) {"?", "?", "?", "?"}
Set Properties and Methods
Set
has methods to add an element to it, delete elements from it, check if an element exists in it, and to clear it completely:
- Use the
size
property to know the size of theSet
. It returns the number of elements in it:
set.size
- Use the
add(element)
method to add an element to theSet
:
// Create a set - saladSet const saladSet = new Set(); // Add some vegetables to it saladSet.add('?'); // tomato saladSet.add('?'); // avocado saladSet.add('?'); // carrot saladSet.add('?'); // cucumber console.log(saladSet); // Output // Set(4) {"?", "?", "?", "?"}
I love cucumbers! How about adding one more?
Oh no, I can't – Set
is a collection of unique elements:
saladSet.add('?'); console.log(saladSet);
The output is the same as before – nothing got added to the saladSet
.
- Use the
has(element)
method to search if we have a carrot (?) or broccoli (?) in theSet
:
// The salad has a ?, so returns true console.log('Does the salad have a carrot?', saladSet.has('?')); // The salad doesn't have a ?, so returns false console.log('Does the salad have broccoli?', saladSet.has('?'));
- Use the
delete(element)
method to remove the avocado(?) from theSet
:
saladSet.delete('?'); console.log('I do not like ?, remove from the salad:', saladSet);
Now our salad Set
is as follows:
Set(3) {"?", "?", "?"}
- Use the
clear()
method to remove all elements from aSet
:
saladSet.clear();
How to Iterate Over a Set
Set
has a method called values()
which returns a SetIterator
to get all its values:
// Create a Set const houseNos = new Set([360, 567, 101]); // Get the SetIterator using the `values()` method console.log(houseNos.values());
Output:
SetIterator {360, 567, 101}
We can use a forEach
or for-of
loop on this to retrieve the values.
Interestingly, JavaScript tries to make Set
compatible with Map
. That's why we find two of the same methods as Map
, keys()
and entries()
.
As Set
doesn't have keys, the keys()
method returns a SetIterator
to retrieve its values:
console.log(houseNos.keys()); // Output // console.log(houseNos.keys());
With Map
, the entries()
method returns an iterator to retrieve key-value pairs. Again there are no keys in a Set
, so entries()
returns a SetIterator
to retrieve the value-value pairs:
console.log(houseNos.entries()); // Output // SetIterator {360 => 360, 567 => 567, 101 => 101}
How to Enumerate over a Set
We can enumerate over a Set using forEach
and for-of
loops:
// with forEach houseNos.forEach((value) => { console.log(value); }); // with for-of for(const value of houseNos) { console.log(value); }
The output of both is:
360 567 101
Sets and Arrays
An array, like a Set
, allows you to add and remove elements. But Set
is quite different, and is not meant to replace arrays.
The major difference between an array and a Set
is that arrays allow duplicate elements. Also, some of the Set
operations like delete()
are faster than array operations like shift()
or splice()
.
Think of Set
as an extension of a regular array, just with more muscles. The Set
data structure is not a replacement of the array
. Both can solve interesting problems.
How to Convert a Set into an array
Converting a Set
into an array is simple:
const arr = [...houseNos]; console.log(arr);
Unique values from an array using the Set
Creating a Set
is a really easy way to remove duplicate values from an array:
// Create a mixedFruit array with a few duplicate fruits const mixedFruit = ['?', '?', '?', '?', '?', '?', '?',]; // Pass the array to create a set of unique fruits const mixedFruitSet = new Set(mixedFruit); console.log(mixedFruitSet);
Output:
Set(4) {"?", "?", "?", "?"}
Set and Object
A Set
can have elements of any type, even objects:
// Create a person object const person = { 'name': 'Alex', 'age': 32 }; // Create a set and add the object to it const pSet = new Set(); pSet.add(person); console.log(pSet);
Output:

No surprise here – the Set
contains one element that is an object.
Let's change a property of the object and add it to the set again:
// Change the name of the person person.name = 'Bob'; // Add the person object to the set again pSet.add(person); console.log(pSet);
What do you think the output will be? Two person
objects or just one?
Here is the output:

Set
is a collection of unique elements. By changing the property of the object, we haven't changed the object itself. Hence Set
will not allow duplicate elements.
Set
is a great data structure to use in addition to JavaScript arrays. It doesn't have a huge advantage over regular arrays, though.
Use Set
when you need to maintain a distinct set of data to perform set operations on like union
, intersection
, difference
, and so on.
In Summary
Here is a GitHub repository to find all the source code used in this article. If you found it helpful, please show your support by giving it a star: //github.com/atapas/js-collections-map-set
You can read more about both the Map
and Set
data structures here:
- Map (MDN)
- Set (MDN)
You may also like some of my other articles:
- My Favorite JavaScript Tips and Tricks
- JavaScript equality and similarity with ==, === and Object.is()
If this article was useful, please share it so others can read it as well. You can @ me on Twitter (@tapasadhikary) with comments, or feel free to follow me.