Telerik blogs

Learn how to leverage JavaScript’s Set with practical examples. This comprehensive guide covers union, difference, symmetricDifference, intersection and more.

Sets are collections in JavaScript that store unique values. Unlike Arrays, Sets automatically handle duplicates and provide powerful operations for working with unique data. While Arrays are great for ordered collections where duplicates are allowed, Sets excel at managing unique items and performing mathematical set operations.

The Set data structure was introduced in ES6, but recent additions have brought more methods that make Sets even more useful for modern development. Let’s explore these new operations and see how they can solve common programming challenges.

Union Operation

The union() method combines two Sets into a new Set containing all unique elements from both Sets. Think of it as merging two collections while automatically removing duplicates.

Example: Managing User Roles

Let’s look at an example where we have various roles for different categories of users, call them basic and admin. We can get all the roles in the system while avoiding duplicates using the union method as follows:

// Define sets of roles for different systems
const basicRoles = new Set(['user', 'viewer', 'commenter']);
const adminRoles = new Set(['admin', 'moderator', 'user']);

// Combine all roles using union
const allRoles = basicRoles.union(adminRoles);

console.log(allRoles); 
// Output: Set (5) {"user", "viewer", "commenter", "admin", "moderator"}

// Notice how 'user' appears only once, even though it was in both sets

This method is useful when you need to combine permissions, features or any collection where duplicates are not needed.

Difference Operation

The difference() method creates a new Set containing elements that exist in the first set but not in the second. It’s like asking, “What do I have that you don’t?”

Example: Finding Unique Items in Shopping Carts

This method comes in handy when doing analytical work. Imagine a scenario where you have two users who bought similar items but you want to find out what’s unique to one of them. Here’s how you’d do that with the difference() method.

// Items in two different shopping carts
const cart1 = new Set(['book', 'laptop', 'headphones', 'mouse']);
const cart2 = new Set(['book', 'laptop', 'keyboard']);

// Find items unique to cart1
const uniqueToCart1 = cart1.difference(cart2);

console.log(uniqueToCart1); 
// Output: Set (2) {"headphones", "mouse"} 

Notice that keyboard, which is unique to cart2, is not included because we’re only looking at what’s unique to cart1. This method is valuable when you need to find items that exist exclusively in one collection but not in another.

Symmetric Difference Operation

The symmetricDifference() method returns elements that are in either Set, but not in both. It’s useful for finding elements that are unique to each Set.

Example: Comparing Feature Flags

Our next example is about feature flags. Feature flags are a software development concept that allows you to enable or disable a feature without modifying the source code or requiring a redeploy. Given two distinct environments, production and development, let’s see how we can find which features are different in those environments:

// Feature flags in different environments
const prodFeatures = new Set(['dark-mode', 'search', 'notifications']);
const devFeatures = new Set(['dark-mode', 'search', 'debug-panel']);

// Find features that differ between environments
const diffFeatures = prodFeatures.symmetricDifference(devFeatures);

console.log([...diffFeatures]); 
// Output: Set (2) {"notifications", "debug-panel"} 

The symmetricDifference() method helps compare two versions or states to find differences, no matter which side they are on.

Intersection Operation

The intersection() method creates a new Set containing only the elements present in both Sets. It’s perfect for finding common elements between two sets.

Example: Finding Common Interests/Hobby

Let’s look at an example where we want to find hobbies that are common between two users:

// User interests
const user1Interests = new Set(['coding', 'music', 'hiking', 'photography']);
const user2Interests = new Set(['gaming', 'music', 'photography', 'cooking']);

// Find common interests
const commonInterests = user1Interests.intersection(user2Interests);

console.log(commonInterests); 
// Output: Set (2) {"music", "photography"} 

Only music and photography are present in both Sets, so they form the intersection. Unique interests such as coding, hiking, gaming and cooking are excluded. In essence, use the intersection() method to identify commonalities between two collections, which can be particularly useful for recommendation systems or matching algorithms.

IsDisjointFrom Operation

The isDisjointFrom() method checks if two Sets have no elements in common. It returns true if the Sets are completely different.

Example: Checking Schedule Conflicts

Imagine if you’re building the next Calendly or a calendar app where you want to check if the meeting about to be scheduled conflicts with an existing meeting. You can do that with isDisjointedFrom(). Here’s how:

// Time slots (simplified as hour numbers)
const meeting1Times = new Set([9, 10, 11]);
const meeting2Times = new Set([14, 15, 16]);

// Check if meetings conflict
const noConflict = meeting1Times.isDisjointFrom(meeting2Times);

console.log(noConflict); // Output: true

This Set operation is ideal for checking if two collections are distinct, which is useful in scheduling, resource allocation or conflict detection scenarios.

IsSubsetOf Operation

The isSubsetOf() method checks if all elements of the first Set exist in the second.

Example: Validating Required Skills

Let’s look at an example to verify that a job candidate meets minimum requirements.

// Required and candidate skills
const requiredSkills = new Set(['typescript', 'react']);
const candidateSkills = new Set(['typescript', 'react', 'node', 'python']);

// Check if candidate has all required skills
const hasRequiredSkills = requiredSkills.isSubsetOf(candidateSkills);

console.log(hasRequiredSkills); // Output: true

Given a collection of required skills and a candidate’s skills, we can determine if the candidate meets the criteria using the isSubsetOf() method.

IsSupersetOf Operation

This isSupersetOf() method verifies if the first Set contains all elements of the second.

Example: Verifying Feature Implementation

// Required and implemented features
const requiredFeatures = new Set(['login', 'signup']);
const implementedFeatures = new Set(['login', 'signup', 'logout', 'profile']);

// Check if all required features are implemented
const allFeaturesImplemented = implementedFeatures.isSupersetOf(requiredFeatures);

console.log(allFeaturesImplemented); // Output: true

This example checks if we implemented all the required features. This is much simpler than writing loops and conditional statements to achieve the same result.

That’s a Wrap

Before ES6, JavaScript didn’t have a data structure for sets. JavaScript now has a Set data structure which can contain arbitrary values and performs membership checks quickly. We explored the new Set operations added after ES6. Here’s what we learned:

  • Use union, difference and intersection for combining/filtering datasets.
  • Apply symmetricDifference for finding unique entries.
  • Leverage isSubsetOf/isSupersetOf for containment checks.
  • Utilize isDisjointFrom for exclusivity verification.
MethodDescriptionReturns
union()All unique elements from both setsNew Set
difference()Elements only in the first setNew Set
symmetricDifference()Elements in either but not bothNew Set
intersection()Elements common to bothNew Set
isDisjointFrom()No shared elementsBoolean
isSubsetOf()All elements contained in other setBoolean
isSupersetOf()Contain all elements of another setBoolean

These operations make Sets an invaluable tool for managing unique collections, comparing data and solving common programming challenges. By mastering these operations, you’ll write more expressive code when working with collections, from user permissions to inventory management. Remember that all mutation-free methods return new Sets, making them safe for functional programming patterns.

The examples provided show practical applications, but there are many more possibilities. As you work with Sets, you’ll discover they can simplify many common programming tasks and make your code more expressive.


Peter Mbanugo
About the Author

Peter Mbanugo

Peter is a software consultant, technical trainer and OSS contributor/maintainer with excellent interpersonal and motivational abilities to develop collaborative relationships among high-functioning teams. He focuses on cloud-native architectures, serverless, continuous deployment/delivery, and developer experience. You can follow him on Twitter.

Related Posts

Comments

Comments are disabled in preview mode.