JavaScript - Tidbits

Like sets and relations in mathematics, JavaScript has built-in objects to demonstrate such logics and make developers’ life more logical, easy going and fun.

JavaScript has a special object called ‘Set’. A Set() is a constructor that creates a set object and holds a few methods as explained here and with help of those methods it can perform different operations of sets like union, intersection, difference etc.

Syntax:
<declaration> <identifier> = new Set()
or
<declaration> <identifier> = new Set(<array>)

Eg:

const a = new Set([1,2,3,4,5])

A Set in JavaScript is a constructor which can only be initialized with new operator. An empty set can also be created and utilized later to add, modify or delete some data with the help of its instance methods.

Like other objects in JavaScript (such as Map), Set has generic properties and methods such as size, has(), keys(), values().

For example, let's consider a new set:

const setSample = new Set([0.1,22,3,43,54,0.5,101,121,200])
setSample.size    // returns: 9
setSample.has(200)  // returns: true
setSample.has(2010)  // returns: false
setSample.keys() // returns set Iterator
setSample.values() // returns set Iterator

Every Set by default contains a special instance methods like keys() and values() which in return creates an iterator object.

  • In JavaScript all built-in iterators inherit from Iterator class

Consider 2 sets A and B and lets go through some basic math:
Union: A∪B
Intersection: A∩B
Difference: A - B ≣ A \ B
SymmetricDifference: (A \ B) ∪ (B \ A)
isSubsetOf: A⊆B
isSupersetOf: A⊇B
isDisjointFrom: A∩B = ∅

A Set constructor holds a collection of instance methods which are used to handle these mathematical operations in JavaScript efficiently.

Let's consider 2 arrays namely ‘arrayA’ and ‘arrayB’ and thier sets ‘setA’ and ‘setB’ respectively:

let arrayA = [0,2,5,7,8,4,6,1], arrayB = [3,9,10,1,12,21,33,42,2];

const setA = new Set(arrayA), setB = new Set(arrayB);

Union of Sets

Use: To find unique features among set-like data entities.

Syntax: <set A>.union(<set B>)

Eg:

setA.union(setB);
// results in:  Set(15) {0,2,5,7,8,4,6,1,3,9,10,12,21,33,42}

It ignores the duplicates elements and makes a set of unique elements.

Intersection of Sets:

Use: To identify similarities between two set-like data entities.

Syntax: <set A>.intersection(<set B>)

Eg:

setA.intersection(setB);
// results in:  Set(2) {2,1}

It gets the common elements among them and ignores the rest of the elements.

Difference of Sets:

Use: To find the features that are present only in the first one among the two set-like data entities.

Syntax: <set A>.difference(<set B>)

Eg:

setA.difference(setB);
// results in:  Set(6) {0,5,7,8,4,6}

setB.difference(setA);
// results in:  Set(7) {3,9,10,12,21,33,42}

setA.difference(setA);
// results in:  Set(0) {}

Symmetric Difference of Sets:

Use: To get rid of the common features among the two data entities. In other words, it is quiet opposite to Intersection.

Syntax: <set A>.symmetricDifference(<set B>)

Eg:

setA.symmetricDifference(setB);
// results in Set(13) {0,5,7,8,4,6,3,9,10,12,21,33,42}

setB.symmetricDifference(setA)
// results in Set(13) {3,9,10,12,21,33,42,0,5,7,8,4,6}

Disjoint Sets:

Use: To verity if both of them do not match each other.

Syntax: <set A>.isDisjointFrom(<set B>)

Eg:

setA.isDisjointFrom(setB);
// results in Set() {}

Subset of Sets:

Use: To verify if the first data entity is a part of the second one.

Syntax: <set A>.isSubsetOf(<set B>)

Eg:

let arrayA = [9,10,1,21], arrayB = [3,9,10,1,12,21,33,42,2];
const setA = new Set(arrayA), setB = new Set(arrayB);
setA.isSubsetOf(setB);
// result is true

setA.isSubsetOf(setA);
// result is true

Superset of Sets:

Use: To verify if the first data entity has the second one as a part of it.

Syntax: <set A>.isSupersetOf(<set B>)

Eg:

let arrayA = [9,10,1,21], arrayB = [3,9,10,1,12,21,33,42,2];
const setA = new Set(arrayA), setB = new Set(arrayB);
setB.isSupersetOf(setA);
// result is true

setB.isSupersetOf(setB);
// result is true

Besides these regular math operations, Set constructor also holds other instance methods to operations like CRUD, iterations etc.

add() delete() clear() size() has() entries() keys() values() forEach() Symbol.iterator next()

Examples of these operations:
Let’s consider arrays p1,p2,p3,p4 and p5.

let p1 = ['ravi',25,'Indian', 'graduate','techie']
let p2 = ['Ravi',32,'Indian', 'graduate','no-techie']
let p3 = ['Ronald',23,'American','highSchool','techie']
let p4 = ['Arun',32,'Indian','graduation','techie']
let p5 = ['Dennis',40,'American', 'under-graduate','non-techie']

Using a Set constructor we can create different sets out of each and every array as shown here:

const setP1 = new Set(p1) 
const setP2 = new Set(p2) 
const setP3 = new Set(p3) 
const setP4 = new Set(p4) 
const setP5 = new Set(p5)
let countryCriteria = ['Indian', 'American','European']
let ageCriteria = [23,25,32,40]
const setCC = new Set(countryCriteria)
const setAC = new Set(ageCriteria)

Advantages of Sets

  • Sets avoid unnecessary iterations through arrays' or objects' data.

  • They do not modify original array of data.

Real-time scenarios

There are some real-time scenarios where Sets make developers' life easy such as when any two data entities (sets) are considered:

  • Useful to find unique entries in a data collection like stores, books, etc.

  • Missing entries from a large data sets (like Censuses in a city) can be found easily with minimal coding efforts.

  • Find out if an existing user is entering / leaving the chat rooms or from online meeting areas.

  • In a large scalable applications, compare and filter the datasets based on certain predefined features and restrict their access to a particular domain routes in that application.

  • Identify similar molecular structures in various chemical composition data.

  • Identify and keep track of similar cyber attacks that happen frequently on a large scale of networking pipelines.

Order of Complexity

Iterators use index numbers to locate their elements where as Sets use Hash tables. Hash table is a data structure and it is a generalization of an ordinary array whose expected time of search reasonably is O(n) where an average value of n=1.

Hash tables are more performant while executing operations like data searching and sorting etc on large data sets. They work on key-index combinations instead of iterating through an entire array of elements.

Order of Complexity of sets can be represented as O(log N), sometimes O(N). It depends on the complexity of the logic written.

Let’s take an example of 2 arrays, find common elements in both of them and remove similar ones from the resultant array. Perform this operation in 2 ways:

  • Without using Sets

  • Using Sets

 let arrResult=[];
 let arr1 = [1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,20,1,2,3,4,5,6,7,8,9,30,1,2,3,4,5,6,7,8,9,40,1,2,3,4,5,6,7,8,9,50,1,2,3,4,5,6,7,8,9,60,1,2,3,4,5,6,7,8,9,70,1,2,3,4,5,6,7,8,9,80,1,2,3,4,5,6,7,8,9,90,1,2,3,4,5,6,7,8,9,100,1,2,3,4,5,6,7,8,9,110,1,2,3,4,5,6,7,8,9,120,1,2,3,4,5,6,7,8,9,130,1,2,3,4,5,6,7,8,9,140,1,2,3,4,5,6,7,8,9,150,1,2,3,4,5,6,7,8,9,160,1,2,3,4,5,6,7,8,9,170,1,2,3,4,5,6,7,8,9,180,1,2,3,4,5,6,7,8,9,190,1,2,3,4,5,6,7,8,9,200];
 // Lenght of arr1 is 200;
 let arr2 = [1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,20,1,2,3,4,5,6,7,8,9,30,1,2,3,4,5,6,7,8,9,40,1,2,3,4,5,6,7,8,9,50,1,2,3,4,5,6,7,8,9,60,1,2,3,4,5,6,7,8,9,70,1,2,3,4,5,6,7,8,9,80,1,2,3,4,5,6,7,8,9,90,1,2,3,4,5,6,7,8,9,100];
 // Lenght of arr1 is 100;

Let arr1 and arr2 are two different arrays (as shown above) with lengths 200 and 100 respectively.

arrResult is an empty array to store the common elements in both the arrays after removing the duplicates.

Without using Sets:

arr1.filter(e=>arr2.includes(e) ? !arrResult.includes(e) ? arrResult.push(e):'':'')
console.log(arrResult);

In this method, the browser takes 0.6000000238418579 milli seconds to execute the logic.

Using Sets

let setArr1 = new Set(arr1); 
let setArr2 = new Set(arr2);
arrResult = [...setArr1.intersection(setArr2)]
console.log(arrResult);

In this method, the browser takes 0.3999999761581421 milli seconds to execute the logic.

In this case, using sets is 66(+)% more performant than the previous method.

2
Subscribe to my newsletter

Read articles from Rajesh Tatavarthy directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Rajesh Tatavarthy
Rajesh Tatavarthy

I am a Front End Engineer / Developer.