Javascript

Javascript Keyed and Indexed Collections Array, Map and Set

javascript collections

In this article we will learn about dealing with collections in Javascript and will take a look at some advanced collections which are Maps and Sets.

 

In javascript there are a lot of methods to deal with collections. Like in languages such as PHP or Java there are collections that has numeric indices and these called indexed collections, collection that has associative indices and these called keyed collections that have a key of any type. In this tutorial we will take a look at each of these methods so let’s begin with arrays.

 

Indexed Collections (Arrays)

arrays is the indexed collection in javascript. Array is an ordered set of values that has a numeric index and value. For example, you could have an array called employees that contains employees’ names indexed by their numerical employee number.

Creating an array

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
var arr = new Array(element0, element1, ...); // First method
var arr = Array(element0, element1, ...); // Second method
var arr = [element0, element1, ...]; // Third method
var arr = new Array(element0, element1, ...); // First method var arr = Array(element0, element1, ...); // Second method var arr = [element0, element1, ...]; // Third method
var arr = new Array(element0, element1, ...);   // First method
var arr = Array(element0, element1, ...);       // Second method
var arr = [element0, element1, ...];            // Third method

as shown above there are a lot of ways of creating arrays. When you initialize arrays in this way the length property is set to the number of arguments supplied.

Another way is to initialize the array with the number of items then add values like this:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
var arr = new Array(5); // initialize array with fixed length
var arr = Array(5); // initialize array with fixed length
// This has exactly the same effect
var arr = [];
arr.length = 5; // initialize array with fixed length
var arr = new Array(5); // initialize array with fixed length var arr = Array(5); // initialize array with fixed length // This has exactly the same effect var arr = []; arr.length = 5; // initialize array with fixed length
var arr = new Array(5);   // initialize array with fixed length 
var arr = Array(5);       // initialize array with fixed length 

// This has exactly the same effect
var arr = [];
arr.length = 5;           // initialize array with fixed length 

If you need to create a variable length array and populate as you go use this approach:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
// first method: initialize empty array then add elements
var employees = [];
employees[0] = 'Casey Jones';
employees[1] = 'Phil Lesh';
employees[2] = 'August West';
// second method: populate an array when you create it
var colors = ['Red', 'Blue', 'Green'];
// first method: initialize empty array then add elements var employees = []; employees[0] = 'Casey Jones'; employees[1] = 'Phil Lesh'; employees[2] = 'August West'; // second method: populate an array when you create it var colors = ['Red', 'Blue', 'Green'];
// first method: initialize empty array then add elements

var employees = [];
employees[0] = 'Casey Jones';
employees[1] = 'Phil Lesh';
employees[2] = 'August West';

// second method: populate an array when you create it
var colors = ['Red', 'Blue', 'Green'];

 

Referring to array elements

To access array elements you use the index of the element as shown here:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
var colors = ['Red', 'Blue', 'Green'];
console.log(colors[0]); // Red
console.log(colors[1]); // Blue
var colors = ['Red', 'Blue', 'Green']; console.log(colors[0]); // Red console.log(colors[1]); // Blue
var colors = ['Red', 'Blue', 'Green'];

console.log(colors[0]);     // Red
console.log(colors[1]);     // Blue

As shown above Arrays is zero based indices which means index of the elements begins with zero so to access the first element you do this with Array[0].

 

Obtaining array length

To get the number of elements in array use Array.length like this:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
console.log(colors.length) // 3
console.log(colors.length) // 3
console.log(colors.length)  // 3

There are some caution when dealing with length property so consider this example:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
var cats = [];
cats[30] = ['Dusty'];
console.log(cats.length); // 31
var cats = []; cats[30] = ['Dusty']; console.log(cats.length); // 31
var cats = [];
cats[30] = ['Dusty'];
console.log(cats.length); // 31

In the above code someone might guess that cats array has one element so it should have a length of 1. But here the first element has index of 30 so if you print  the array it will show 31 elements starting with zero and this is because the length property always returns the index of the last element plus one (as above 30 + 1) = 31.

 

Iterating over arrays

There are multiple ways to iterate over arrays. First way using standard for loop:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
var colors = ['red', 'green', 'blue'];
for (var i = 0; i < colors.length; i++) {
console.log(colors[i]);
}
// red
// green
// blue
var colors = ['red', 'green', 'blue']; for (var i = 0; i < colors.length; i++) { console.log(colors[i]); } // red // green // blue
var colors = ['red', 'green', 'blue'];
for (var i = 0; i < colors.length; i++) {
  console.log(colors[i]);
}

// red
// green
// blue

The forEach() method provides another way of iterating over an array:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
var colors = ['red', 'green', 'blue'];
colors.forEach(function(color) {
console.log(color);
});
// red
// green
// blue
var colors = ['red', 'green', 'blue']; colors.forEach(function(color) { console.log(color); }); // red // green // blue
var colors = ['red', 'green', 'blue'];

colors.forEach(function(color) {
  console.log(color);
});

// red
// green
// blue

Alternatively, You can shorten the code for the forEach parameter with ES2015 Arrow Functions:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
var colors = ['red', 'green', 'blue'];
colors.forEach(color => console.log(color));
// red
// green
// blue
var colors = ['red', 'green', 'blue']; colors.forEach(color => console.log(color)); // red // green // blue
var colors = ['red', 'green', 'blue'];

colors.forEach(color => console.log(color)); 

// red
// green
// blue

 

Array methods

concat() joins two arrays and returns a new array.

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
var myArray = new Array('1', '2', '3');
myArray = myArray.concat('a', 'b', 'c');
// myArray is now ["1", "2", "3", "a", "b", "c"]
var myArray = new Array('1', '2', '3'); myArray = myArray.concat('a', 'b', 'c'); // myArray is now ["1", "2", "3", "a", "b", "c"]
var myArray = new Array('1', '2', '3');
myArray = myArray.concat('a', 'b', 'c'); 

// myArray is now ["1", "2", "3", "a", "b", "c"]

 

join(delimiter = ',') joins all elements of an array into a string.

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
var employees = new Array('Jonn', 'Adham', 'Amr');
var list = employees.join(' - '); // list is "Jonn - Adham - Amr"
var employees = new Array('Jonn', 'Adham', 'Amr'); var list = employees.join(' - '); // list is "Jonn - Adham - Amr"
var employees = new Array('Jonn', 'Adham', 'Amr');
var list = employees.join(' - ');      // list is "Jonn - Adham - Amr"

 

push() adds one or more elements to the end of an array and returns the resulting length of the array.

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
var numbers = new Array('1', '2');
numbers.push('3'); // numbers is now ["1", "2", "3"]
var numbers = new Array('1', '2'); numbers.push('3'); // numbers is now ["1", "2", "3"]
var numbers = new Array('1', '2');
numbers.push('3'); // numbers is now ["1", "2", "3"]

 

pop() removes the last element from an array and returns that element.

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
var numbers = new Array('1', '2', '3');
var last = numbers.pop();
// numbers is now ["1", "2"], last = "3"
var numbers = new Array('1', '2', '3'); var last = numbers.pop(); // numbers is now ["1", "2"], last = "3"
var numbers = new Array('1', '2', '3');
var last = numbers.pop(); 
// numbers is now ["1", "2"], last = "3"

 

shift() removes the first element from an array and returns that element.

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
var numbers = new Array('1', '2', '3');
var first = numbers.shift();
// numbers is now ["2", "3"], first is "1"
var numbers = new Array('1', '2', '3'); var first = numbers.shift(); // numbers is now ["2", "3"], first is "1"
var numbers = new Array('1', '2', '3');
var first = numbers.shift(); 

// numbers is now ["2", "3"], first is "1"

 

unshift() adds one or more elements to the front of an array and returns the new length of the array.

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
var numbers = new Array('1', '2', '3');
numbers.unshift('4', '5');
// numbers becomes ["4", "5", "1", "2", "3"]
var numbers = new Array('1', '2', '3'); numbers.unshift('4', '5'); // numbers becomes ["4", "5", "1", "2", "3"]
var numbers = new Array('1', '2', '3');
numbers.unshift('4', '5'); 

// numbers becomes ["4", "5", "1", "2", "3"]

 

slice(start_index, upto_index) extracts a section of an array and returns a new array.

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
var letters = new Array('a', 'b', 'c', 'd', 'e');
letters = letters.slice(1, 4); // starts at index 1 and extracts all elements
// until index 3, returning [ "b", "c", "d"]
var letters = new Array('a', 'b', 'c', 'd', 'e'); letters = letters.slice(1, 4); // starts at index 1 and extracts all elements // until index 3, returning [ "b", "c", "d"]
var letters = new Array('a', 'b', 'c', 'd', 'e');
letters = letters.slice(1, 4); // starts at index 1 and extracts all elements
                               // until index 3, returning [ "b", "c", "d"]

 

splice(index, count_to_remove, addElement1, addElement2, ...)

removes elements from an array and (optionally) replaces them. It returns the items which were removed from the array.

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
var numbers = new Array('1', '2', '3', '4', '5');
numbers.splice(1, 3, 'a', 'b', 'c', 'd');
// numbers is now ["1", "a", "b", "c", "d", "5"]
// This code started at index one (or where the "2" was),
// removed 3 elements there, and then inserted all consecutive
// elements in its place.
var numbers = new Array('1', '2', '3', '4', '5'); numbers.splice(1, 3, 'a', 'b', 'c', 'd'); // numbers is now ["1", "a", "b", "c", "d", "5"] // This code started at index one (or where the "2" was), // removed 3 elements there, and then inserted all consecutive // elements in its place.
var numbers = new Array('1', '2', '3', '4', '5');
numbers.splice(1, 3, 'a', 'b', 'c', 'd'); 
// numbers is now ["1", "a", "b", "c", "d", "5"]
// This code started at index one (or where the "2" was), 
// removed 3 elements there, and then inserted all consecutive
// elements in its place.

 

reverse() transposes the elements of an array, in place: the first array element becomes the last and the last becomes the first. It returns a reference to the array.

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
var numbers = new Array('1', '2', '3');
numbers.reverse();
// transposes the array so that numbers = ["3", "2", "1"]
var numbers = new Array('1', '2', '3'); numbers.reverse(); // transposes the array so that numbers = ["3", "2", "1"]
var numbers = new Array('1', '2', '3');
numbers.reverse(); 
// transposes the array so that numbers = ["3", "2", "1"]

 

sort() sorts the elements of an array in place, and returns a reference to the array.

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
var myArray = new Array('Wind', 'Rain', 'Fire');
myArray.sort();
// sorts the array so that myArray = ["Fire", "Rain", "Wind"]
var myArray = new Array('Wind', 'Rain', 'Fire'); myArray.sort(); // sorts the array so that myArray = ["Fire", "Rain", "Wind"]
var myArray = new Array('Wind', 'Rain', 'Fire');
myArray.sort(); 

// sorts the array so that myArray = ["Fire", "Rain", "Wind"]

 

indexOf(searchElement[, fromIndex]) searches the array for searchElement and returns the index of the first match.

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
var a = ['a', 'b', 'a', 'b', 'a'];
console.log(a.indexOf('b')); // logs 1
var a = ['a', 'b', 'a', 'b', 'a']; console.log(a.indexOf('b')); // logs 1
var a = ['a', 'b', 'a', 'b', 'a'];

console.log(a.indexOf('b')); // logs 1

 

map(callback[, thisObject]) returns a new array of the return value from executing callback on every array item.

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
var a1 = ['a', 'b', 'c'];
var a2 = a1.map(function(item) { return item.toUpperCase(); });
console.log(a2); // logs ['A', 'B', 'C']
var a1 = ['a', 'b', 'c']; var a2 = a1.map(function(item) { return item.toUpperCase(); }); console.log(a2); // logs ['A', 'B', 'C']
var a1 = ['a', 'b', 'c'];
var a2 = a1.map(function(item) { return item.toUpperCase(); });
console.log(a2); // logs ['A', 'B', 'C']

 

filter(callback[, thisObject]) returns a new array containing the items for which callback returned true.

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
var a1 = ['a', 10, 'b', 20, 'c', 30];
var a2 = a1.filter(function(item) { return typeof item === 'number'; });
console.log(a2); // logs [10, 20, 30]
var a1 = ['a', 10, 'b', 20, 'c', 30]; var a2 = a1.filter(function(item) { return typeof item === 'number'; }); console.log(a2); // logs [10, 20, 30]
var a1 = ['a', 10, 'b', 20, 'c', 30];
var a2 = a1.filter(function(item) { return typeof item === 'number'; });
console.log(a2); // logs [10, 20, 30]

 

Keyed Collections

keyed collections or in some terms called associative. Collections of data which are ordered by a key, Map and Set objects contain elements which are iterable in the order of insertion.

 

Maps

ECMAScript 2015 introduces a new data structure to map values to values. A Map object is a simple key/value map and can iterate its elements in order of insertion.

Syntax

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
let myMap = new Map([iterable]); // create a new map object
let myMap = new Map([iterable]); // create a new map object
let myMap = new Map([iterable]);   // create a new map object 

Map take optional parameter iterable which is an Array or other iterable object whose elements are key-value pairs.

 

Adding elements

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
myMap.set('key1', 'value1');
myMap.set('key2', 'value2');
myMap.set('key3', 'value3');
myMap.set('key1', 'value1'); myMap.set('key2', 'value2'); myMap.set('key3', 'value3');
myMap.set('key1', 'value1');
myMap.set('key2', 'value2');
myMap.set('key3', 'value3');

As shown in the code above to add elements to the map use Map.set(key, value).

 

Map properties and methods

Retrieve the size of map with Map.size property:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
console.log(myMap.size); // 3
console.log(myMap.size); // 3
console.log(myMap.size);     // 3

Get specific item by key with Map.get(key):

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
console.log(myMap.get('key1')) // value1
console.log(myMap.get('key7')) // undefined
console.log(myMap.get('key1')) // value1 console.log(myMap.get('key7')) // undefined
console.log(myMap.get('key1'))   // value1
console.log(myMap.get('key7'))   // undefined

Check if an item exists with Map.has(key):

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
console.log(myMap.has('key1')) // true
console.log(myMap.has('key10')) // false
console.log(myMap.has('key1')) // true console.log(myMap.has('key10')) // false
console.log(myMap.has('key1'))  // true
console.log(myMap.has('key10')) // false

To delete an item from map use Map.delete(key):

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
myMap.delete('key1')
myMap.delete('key1')
myMap.delete('key1')

Clear all the map elements with Map.clear():

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
myMap.clear()
myMap.clear()
myMap.clear()

 

Iterating over map items:

Maps can be iterated using a for..of loop as shown here:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
for (var [key, value] of myMap) {
console.log(key + ' -> ' + value);
}
// key1 -> value1
// key2 -> value2
// key3 -> value3
for (var [key, value] of myMap) { console.log(key + ' -> ' + value); } // key1 -> value1 // key2 -> value2 // key3 -> value3
for (var [key, value] of myMap) {
       console.log(key + ' -> ' + value);
}
// key1 -> value1
// key2 -> value2
// key3 -> value3

Maps also can be iterated using the forEach() method:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
myMap.forEach(function(value, key) {
console.log(key + ' -> ' + value);
});
// key1 -> value1
// key2 -> value2
// key3 -> value3
myMap.forEach(function(value, key) { console.log(key + ' -> ' + value); }); // key1 -> value1 // key2 -> value2 // key3 -> value3
myMap.forEach(function(value, key) {
  console.log(key + ' -> ' + value);
});
// key1 -> value1
// key2 -> value2
// key3 -> value3

 

Let’s look at some examples:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
var languages = new Map();
languages.set('php', 'web programming');
languages.set('c', 'system programming');
languages.set('opengl', 'game programming');
console.log(languages.size); // 3
console.log(languages.get('java')); // undefined
console.log(languages.has('java')); // false
languages.delete('opengl');
console.log(languages.has('opengl')); // false
for (var [key, value] of languages) {
console.log(key + ' used for ' + value);
}
// php used for web programming
// c used for system programming
// opengl used for game programming
languages.clear();
console.log(languages.size); // 0
var languages = new Map(); languages.set('php', 'web programming'); languages.set('c', 'system programming'); languages.set('opengl', 'game programming'); console.log(languages.size); // 3 console.log(languages.get('java')); // undefined console.log(languages.has('java')); // false languages.delete('opengl'); console.log(languages.has('opengl')); // false for (var [key, value] of languages) { console.log(key + ' used for ' + value); } // php used for web programming // c used for system programming // opengl used for game programming languages.clear(); console.log(languages.size); // 0
var languages = new Map();
languages.set('php', 'web programming');
languages.set('c', 'system programming');
languages.set('opengl', 'game programming');

console.log(languages.size);            // 3
console.log(languages.get('java'));     // undefined
console.log(languages.has('java'));     // false
languages.delete('opengl');
console.log(languages.has('opengl'));    // false

for (var [key, value] of languages) {
	console.log(key + ' used for ' + value);
}
// php used for web programming
// c used for system programming
// opengl used for game programming

languages.clear();
console.log(languages.size);  // 0
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
var myMap = new Map();
var keyString = 'a string',
keyObj = {},
keyFunc = function() {};
// setting the values
myMap.set(keyString, "value associated with 'a string'");
myMap.set(keyObj, 'value associated with keyObj');
myMap.set(keyFunc, 'value associated with keyFunc');
myMap.size; // 3
// getting the values
myMap.get(keyString); // "value associated with 'a string'"
myMap.get(keyObj); // "value associated with keyObj"
myMap.get(keyFunc); // "value associated with keyFunc"
myMap.get('a string'); // "value associated with 'a string'"
// because keyString === 'a string'
myMap.get({}); // undefined, because keyObj !== {}
myMap.get(function() {}) // undefined, because keyFunc !== function () {}
var myMap = new Map(); var keyString = 'a string', keyObj = {}, keyFunc = function() {}; // setting the values myMap.set(keyString, "value associated with 'a string'"); myMap.set(keyObj, 'value associated with keyObj'); myMap.set(keyFunc, 'value associated with keyFunc'); myMap.size; // 3 // getting the values myMap.get(keyString); // "value associated with 'a string'" myMap.get(keyObj); // "value associated with keyObj" myMap.get(keyFunc); // "value associated with keyFunc" myMap.get('a string'); // "value associated with 'a string'" // because keyString === 'a string' myMap.get({}); // undefined, because keyObj !== {} myMap.get(function() {}) // undefined, because keyFunc !== function () {}
var myMap = new Map();

var keyString = 'a string',
    keyObj = {},
    keyFunc = function() {};

// setting the values
myMap.set(keyString, "value associated with 'a string'");
myMap.set(keyObj, 'value associated with keyObj');
myMap.set(keyFunc, 'value associated with keyFunc');

myMap.size; // 3

// getting the values
myMap.get(keyString);    // "value associated with 'a string'"
myMap.get(keyObj);       // "value associated with keyObj"
myMap.get(keyFunc);      // "value associated with keyFunc"

myMap.get('a string');   // "value associated with 'a string'"
                         // because keyString === 'a string'
myMap.get({});           // undefined, because keyObj !== {}
myMap.get(function() {}) // undefined, because keyFunc !== function () {}

As shown in the code above the Map keys can be anything (primitive values, objects or functions).

Using NaN as Map keys

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
var myMap = new Map();
myMap.set(NaN, 'not a number');
myMap.get(NaN); // "not a number"
var otherNaN = Number('foo');
myMap.get(otherNaN); // "not a number"
var myMap = new Map(); myMap.set(NaN, 'not a number'); myMap.get(NaN); // "not a number" var otherNaN = Number('foo'); myMap.get(otherNaN); // "not a number"
var myMap = new Map();
myMap.set(NaN, 'not a number');

myMap.get(NaN); // "not a number"

var otherNaN = Number('foo');
myMap.get(otherNaN); // "not a number"

NaN can also be used as a key. Even though every NaN is not equal to itself (NaN !== NaN is true), the following example works because NaNs are indistinguishable from each other.

 

Demonstrating keys(), values(), and entries():

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
var myMap = new Map();
myMap.set(0, 'zero');
myMap.set(1, 'one');
for (var [key, value] of myMap) {
console.log(key + ' = ' + value);
}
// 0 = zero
// 1 = one
for (var key of myMap.keys()) {
console.log(key);
}
// 0
// 1
for (var value of myMap.values()) {
console.log(value);
}
// zero
// one
for (var [key, value] of myMap.entries()) {
console.log(key + ' = ' + value);
}
// 0 = zero
// 1 = one
var myMap = new Map(); myMap.set(0, 'zero'); myMap.set(1, 'one'); for (var [key, value] of myMap) { console.log(key + ' = ' + value); } // 0 = zero // 1 = one for (var key of myMap.keys()) { console.log(key); } // 0 // 1 for (var value of myMap.values()) { console.log(value); } // zero // one for (var [key, value] of myMap.entries()) { console.log(key + ' = ' + value); } // 0 = zero // 1 = one
var myMap = new Map();
myMap.set(0, 'zero');
myMap.set(1, 'one');
for (var [key, value] of myMap) {
  console.log(key + ' = ' + value);
}
// 0 = zero
// 1 = one

for (var key of myMap.keys()) {
  console.log(key);
}
// 0
// 1

for (var value of myMap.values()) {
  console.log(value);
}
// zero
// one

for (var [key, value] of myMap.entries()) {
  console.log(key + ' = ' + value);
}
// 0 = zero
// 1 = one

 

 

Object and Map Differences:

Traditionally, objects have been used to map strings to values. Objects allow you to set keys to values, retrieve those values, delete keys, and detect whether something is stored at a key. Map objects, however, have a few more advantages that make them better maps.

  • The keys of an Object are Strings, where they can be of any value for a Map.
  • You can get the size of a Map easily while you have to manually keep track of size for an Object.
  • The iteration of maps is in insertion order of the elements.
  • An Object has a prototype, so there are default keys in the map. (this can be bypassed using map = Object.create(null)).

 

Converting Maps To Arrays and vice versa:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
var kvArray = [['key1', 'value1'], ['key2', 'value2']];
// Use the regular Map constructor to transform a 2D key-value Array into a map
var myMap = new Map(kvArray);
myMap.get('key1'); // returns "value1"
// Use the Array.from function to transform a map into a 2D key-value Array
console.log(Array.from(myMap)); // Will show you exactly the same Array as kvArray
// Or use the keys or values iterators and convert them to an array
console.log(Array.from(myMap.keys())); // Will show ["key1", "key2"]
console.log(Array.from(myMap.values())); // Will show ["value1", "value2"]
var kvArray = [['key1', 'value1'], ['key2', 'value2']]; // Use the regular Map constructor to transform a 2D key-value Array into a map var myMap = new Map(kvArray); myMap.get('key1'); // returns "value1" // Use the Array.from function to transform a map into a 2D key-value Array console.log(Array.from(myMap)); // Will show you exactly the same Array as kvArray // Or use the keys or values iterators and convert them to an array console.log(Array.from(myMap.keys())); // Will show ["key1", "key2"] console.log(Array.from(myMap.values())); // Will show ["value1", "value2"]
var kvArray = [['key1', 'value1'], ['key2', 'value2']];

// Use the regular Map constructor to transform a 2D key-value Array into a map
var myMap = new Map(kvArray);

myMap.get('key1'); // returns "value1"

// Use the Array.from function to transform a map into a 2D key-value Array
console.log(Array.from(myMap)); // Will show you exactly the same Array as kvArray

// Or use the keys or values iterators and convert them to an array
console.log(Array.from(myMap.keys())); // Will show ["key1", "key2"]
console.log(Array.from(myMap.values())); // Will show ["value1", "value2"]

 

Sets

The Set object lets you store unique values of any type, whether primitive values or object references. Set differs from Maps in that it does not contain explicit keys because it’s a collection of values and keys is the same as values.

Like Maps you can iterate Set elements in the order of insertion. But note that a value in a Set may only occur once; it is unique in the Set‘s collection.

Syntax

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
let mySet = new Set([iterable]); // create a new set object
let mySet = new Set([iterable]); // create a new set object
let mySet = new Set([iterable]);   // create a new set object 

If an iterable object is passed, all of its elements will be added to the new Set. If you don’t specify this parameter, or its value is null, the new Set is empty.

 

Adding Elements

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
mySet.add(1);
mySet.add(5);
mySet.add(10);
mySet.add(10); // will be deleted because its aleardy exist
mySet.add(undefined);
mySet.add(NaN);
mySet.add('some text');
mySet.add({a: 1, b: 2});
mySet.add([1, 2, 3]);
mySet.add(1); mySet.add(5); mySet.add(10); mySet.add(10); // will be deleted because its aleardy exist mySet.add(undefined); mySet.add(NaN); mySet.add('some text'); mySet.add({a: 1, b: 2}); mySet.add([1, 2, 3]);
mySet.add(1);
mySet.add(5);
mySet.add(10);
mySet.add(10);          // will be deleted because its aleardy exist
mySet.add(undefined);   
mySet.add(NaN);
mySet.add('some text');
mySet.add({a: 1, b: 2});
mySet.add([1, 2, 3]);

As shown above you can add any arbitrary values in the Set. You can add primitive values, objects, arrays, also undefined and Nan.

 

Set properties and methods

Retrieve the size of set with Set.size property:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
console.log(mySet.size); // 8
console.log(mySet.size); // 8
console.log(mySet.size);     // 8

Check if a value exists with Set.has(value):

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
console.log(mySet.has(10)) // true
console.log(mySet.has(1000)) // false
console.log(mySet.has(10)) // true console.log(mySet.has(1000)) // false
console.log(mySet.has(10))     // true
console.log(mySet.has(1000))   // false

To remove an element from set use Set.delete(value):

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
mySet.delete(5);
mySet.delete(5);
mySet.delete(5); 

To clear all Set values use Set.clear():

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
mySet.clear();
mySet.clear();
mySet.clear();

 

Iterating over set items:

using for .. of loop as shown in this code:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
// iterate over items in set
for (let item of mySet) {
console.log(item);
}
// logs the items in the order:
// 1
// 5
// 10
// undefined
// NaN
// "some text"
// {"a": 1, "b": 2}
// [1, 2, 3]
// iterate over items in set for (let item of mySet) { console.log(item); } // logs the items in the order: // 1 // 5 // 10 // undefined // NaN // "some text" // {"a": 1, "b": 2} // [1, 2, 3]
// iterate over items in set

for (let item of mySet) { 
    console.log(item);
}

// logs the items in the order: 
// 1
// 5 
// 10 
// undefined
// NaN
// "some text"
// {"a": 1, "b": 2}
// [1, 2, 3] 

You can also iterate Sets using Set.forEach(callback):

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
// Iterate set entries with forEach
mySet.forEach(function(value) {
console.log(value);
});
// Iterate set entries with forEach mySet.forEach(function(value) { console.log(value); });
// Iterate set entries with forEach
mySet.forEach(function(value) {
  console.log(value);
});

 



Let’s look at few examples:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
var mySet = new Set();
mySet.add(1);
mySet.add('some text');
mySet.add('foo');
mySet.has(1); // true
mySet.delete('foo');
mySet.size; // 2
for (let item of mySet) console.log(item);
// 1
// "some text"
var mySet = new Set(); mySet.add(1); mySet.add('some text'); mySet.add('foo'); mySet.has(1); // true mySet.delete('foo'); mySet.size; // 2 for (let item of mySet) console.log(item); // 1 // "some text"
var mySet = new Set();
mySet.add(1);
mySet.add('some text');
mySet.add('foo');

mySet.has(1); // true
mySet.delete('foo');
mySet.size; // 2

for (let item of mySet) console.log(item);
// 1
// "some text"
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
var mySet = new Set();
mySet.add(1); // Set [ 1 ]
mySet.add(5); // Set [ 1, 5 ]
mySet.add(5); // Set [ 1, 5 ]
mySet.add('some text'); // Set [ 1, 5, 'some text' ]
var o = {a: 1, b: 2};
mySet.add(o);
mySet.add({a: 1, b: 2}); // o is referencing a different object so this is okay
mySet.has(1); // true
mySet.has(3); // false, 3 has not been added to the set
mySet.has(5); // true
mySet.has(Math.sqrt(25)); // true
mySet.has('Some Text'.toLowerCase()); // true
mySet.has(o); // true
mySet.size; // 5
mySet.delete(5); // removes 5 from the set
mySet.has(5); // false, 5 has been removed
mySet.size; // 4, we just removed one value
console.log(mySet);// Set [ 1, "some text", Object {a: 1, b: 2}, Object {a: 1, b: 2} ]
var mySet = new Set(); mySet.add(1); // Set [ 1 ] mySet.add(5); // Set [ 1, 5 ] mySet.add(5); // Set [ 1, 5 ] mySet.add('some text'); // Set [ 1, 5, 'some text' ] var o = {a: 1, b: 2}; mySet.add(o); mySet.add({a: 1, b: 2}); // o is referencing a different object so this is okay mySet.has(1); // true mySet.has(3); // false, 3 has not been added to the set mySet.has(5); // true mySet.has(Math.sqrt(25)); // true mySet.has('Some Text'.toLowerCase()); // true mySet.has(o); // true mySet.size; // 5 mySet.delete(5); // removes 5 from the set mySet.has(5); // false, 5 has been removed mySet.size; // 4, we just removed one value console.log(mySet);// Set [ 1, "some text", Object {a: 1, b: 2}, Object {a: 1, b: 2} ]
var mySet = new Set();

mySet.add(1); // Set [ 1 ]
mySet.add(5); // Set [ 1, 5 ]
mySet.add(5); // Set [ 1, 5 ]
mySet.add('some text'); // Set [ 1, 5, 'some text' ]
var o = {a: 1, b: 2};
mySet.add(o);

mySet.add({a: 1, b: 2}); // o is referencing a different object so this is okay

mySet.has(1); // true
mySet.has(3); // false, 3 has not been added to the set
mySet.has(5);              // true
mySet.has(Math.sqrt(25));  // true
mySet.has('Some Text'.toLowerCase()); // true
mySet.has(o); // true

mySet.size; // 5

mySet.delete(5); // removes 5 from the set
mySet.has(5);    // false, 5 has been removed

mySet.size; // 4, we just removed one value
console.log(mySet);// Set [ 1, "some text", Object {a: 1, b: 2}, Object {a: 1, b: 2} ]

 

Set keys(), values(), and entries():

values() returns a new Iterator object that contains the values for each element in the Set object in insertion order.

keys() is the same function as the values() function and returns a new Iterator object that contains the values for each element in the Set object in insertion order.

entries() returns a new Iterator object that contains an array of [value, value] for each element in the Set object, in insertion order

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
for (let item of mySet.keys()) console.log(item);
for (let item of mySet.values()) console.log(item);
for (let [key, value] of mySet.entries()) console.log(key);
var myArr = Array.from(mySet);
// the following will also work if run in an HTML document
mySet.add(document.body);
mySet.has(document.querySelector('body')); // true
// converting between Set and Array
mySet2 = new Set([1, 2, 3, 4]);
mySet2.size; // 4
[...mySet2]; // [1, 2, 3, 4]
// intersect can be simulated via
var intersection = new Set([...set1].filter(x => set2.has(x)));
// difference can be simulated via
var difference = new Set([...set1].filter(x => !set2.has(x)));
// Iterate set entries with forEach
mySet.forEach(function(value) {
console.log(value);
});
for (let item of mySet.keys()) console.log(item); for (let item of mySet.values()) console.log(item); for (let [key, value] of mySet.entries()) console.log(key); var myArr = Array.from(mySet); // the following will also work if run in an HTML document mySet.add(document.body); mySet.has(document.querySelector('body')); // true // converting between Set and Array mySet2 = new Set([1, 2, 3, 4]); mySet2.size; // 4 [...mySet2]; // [1, 2, 3, 4] // intersect can be simulated via var intersection = new Set([...set1].filter(x => set2.has(x))); // difference can be simulated via var difference = new Set([...set1].filter(x => !set2.has(x))); // Iterate set entries with forEach mySet.forEach(function(value) { console.log(value); });
for (let item of mySet.keys()) console.log(item);
 
for (let item of mySet.values()) console.log(item);

for (let [key, value] of mySet.entries()) console.log(key);

var myArr = Array.from(mySet); 

// the following will also work if run in an HTML document
mySet.add(document.body);
mySet.has(document.querySelector('body')); // true

// converting between Set and Array
mySet2 = new Set([1, 2, 3, 4]);
mySet2.size; // 4
[...mySet2]; // [1, 2, 3, 4]

// intersect can be simulated via 
var intersection = new Set([...set1].filter(x => set2.has(x)));

// difference can be simulated via
var difference = new Set([...set1].filter(x => !set2.has(x)));

// Iterate set entries with forEach
mySet.forEach(function(value) {
  console.log(value);
});

 

Array and Set Differences:

Traditionally, a set of elements has been stored in arrays in JavaScript in a lot of situations. The new Set object, however, has some advantages:

  • Checking whether an element exists in a collection using indexOf for arrays is slow.
  • Set objects let you delete elements by their value. With an array you would have to splice based on an element’s index.
  • The value NaN cannot be found with indexOf in an array.
  • Set objects store unique values; you don’t have to keep track of duplicates by yourself.

 

Converting Sets To Arrays and vice versa:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
var myArray = ['value1', 'value2', 'value3'];
// Use the regular Set constructor to transform an Array into a Set
var mySet = new Set(myArray);
mySet.has('value1'); // returns true
// Use the spread operator to transform a set into an Array.
console.log([...mySet]); // Will show you exactly the same Array as myArray
var myArray = ['value1', 'value2', 'value3']; // Use the regular Set constructor to transform an Array into a Set var mySet = new Set(myArray); mySet.has('value1'); // returns true // Use the spread operator to transform a set into an Array. console.log([...mySet]); // Will show you exactly the same Array as myArray
var myArray = ['value1', 'value2', 'value3'];

// Use the regular Set constructor to transform an Array into a Set
var mySet = new Set(myArray);

mySet.has('value1'); // returns true

// Use the spread operator to transform a set into an Array.
console.log([...mySet]); // Will show you exactly the same Array as myArray

 

5 1 vote
Article Rating

What's your reaction?

Excited
4
Happy
4
Not Sure
0
Confused
0

You may also like

Subscribe
Notify of
guest


1 Comment
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Rohit
Rohit
3 years ago

best