This content originally appeared on Telerik Blogs and was authored by Peter Mbanugo
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
andintersection
for combining/filtering datasets. - Apply
symmetricDifference
for finding unique entries. - Leverage
isSubsetOf
/isSupersetOf
for containment checks. - Utilize
isDisjointFrom
for exclusivity verification.
Method | Description | Returns |
---|---|---|
union() | All unique elements from both sets | New Set |
difference() | Elements only in the first set | New Set |
symmetricDifference() | Elements in either but not both | New Set |
intersection() | Elements common to both | New Set |
isDisjointFrom() | No shared elements | Boolean |
isSubsetOf() | All elements contained in other set | Boolean |
isSupersetOf() | Contain all elements of another set | Boolean |
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.
This content originally appeared on Telerik Blogs and was authored by Peter Mbanugo