https://developer.mozilla.org/en-US/blog/javascript-set-methods/
* Skip to main content
* Skip to search
Open main menu
* ReferencesReferences
+
Overview / Web Technology
Web technology reference for developers
+
HTML
Structure of content on the web
+
CSS
Code used to describe document style
+
JavaScript
General-purpose scripting language
+
HTTP
Protocol for transmitting web resources
+
Web APIs
Interfaces for building web applications
+
Web Extensions
Developing extensions for web browsers
+
Web Technology
Web technology reference for developers
* GuidesGuides
+
Overview / MDN Learning Area
Learn web development
+
MDN Learning Area
Learn web development
+
HTML
Learn to structure web content with HTML
+
CSS
Learn to style content using CSS
+
JavaScript
Learn to run scripts in the browser
+
Accessibility
Learn to make the web accessible to all
* PlusPlus
+
Overview
A customized MDN experience
+
AI Help (beta)
Get real-time assistance and support
+
Updates
All browser compatibility updates at a glance
+
Documentation
Learn how to use MDN Plus
+
FAQ
Frequently asked questions about MDN Plus
* Curriculum^New
* Blog
* Play
* AI Help ^Beta
Search MDN[ ]Clear search inputSearch
Theme
* Log in
* Sign up for free
In this article
* What's new in Set methods?
* What is a JavaScript Set?
* Union of two sets
* Set intersection
* Set symmetric difference
* Set difference
* Subset, superset, and disjoint from
* Summary
New JavaScript Set methods title. A vibrant gradient with a
JavaScript logo in the bottom-left corner and a venn diagram in the
top-right corner.
New JavaScript Set methods
Author avatarBrian SmithJune 24, 20246 minute read
New JavaScript Set methods are arriving! Since Firefox 127, these
methods are available in most major browser engines, which means you
won't need a polyfill to make them work everywhere.
This article is a good read for people who are new to Set in
JavaScript and are looking to find out how to use these new
JavaScript methods. I'll highlight some advantages of using these
methods with basic examples to show why you might reach for these
instead of building your own implementations.
What's new in Set methods?
For those of you looking for the TL;DR, here's the gist of new
methods that have cross-browser support:
* intersection() returns a new set with elements in both this set
and the given set.
* union() returns a new set with all elements in this set and the
given set.
* difference() returns a new set with elements in this set but not
in the given set.
* symmetricDifference() returns a new set with elements in either
set, but not in both.
* isSubsetOf() returns a boolean indicating if all elements of a
set are in a specific set.
* isSupersetOf() returns a boolean indicating if all elements of a
set are in a specific set.
* isDisjointFrom() returns a boolean indicating if this set has no
elements in common with a specific set.
If you've read (or skimmed) through the above list and are confused,
don't worry, we'll describe what they do in the following sections.
Each of these methods are used to check what the contents of sets are
compared to the contents of another specific set.
What is a JavaScript Set?
A set is similar to an Array, except that each value can only be
stored once. For example, we can take a list of items, add them all
to a set, and then inspect the results of the set. The list on the
right is the contents of the
list on the left, but converted to
a set. We have all duplicates removed from the list because we're
guaranteed that a set is unique:
My list
- apple
- pear
- carrot
- pear
- apple
- yoshi
const allListItems = document.querySelectorAll("li");
const setList = document.getElementById("set");
// Create a new set and add list items
const mySet = new Set();
allListItems.forEach((item) => {
mySet.add(item.textContent);
});
// List the items in the set
mySet.forEach((item) => {
const li = document.createElement("li");
li.textContent = item;
setList.appendChild(li);
});
body {
font-family: monospace;
}
#container {
display: flex;
gap: 1rem;
justify-content: space-evenly;
}
This might not look like much in a small example such as this, but
it's really convenient to have a built-in way to make unique
collections of items, especially over larger data and more complex
data types and objects. For example, consider that you can add
elements to a set like so:
js
const dogs = new Set();
const yoshi = { name: "Yoshi", personality: "Friendly" };
dogs.add(yoshi);
It's also typically faster to check if an element is in a set as
opposed to in an Array, so this fits use cases where you need to keep
an eye on performance in larger data sets. You can also compose new
sets with specific logical properties based on existing sets, and
we'll take a look at some examples of that below.
We'll be covering all of the new methods below, but if you want to
see everything you can do with a Set, check the Instance methods
documentation.
Union of two sets
This is a good example to start us off if you're not familiar with
sets. With the union, we can check what elements are in 'either or
both' sets. In the example below, we have two lists and we want to
make a third one that contains all items from both lists, but without
duplicates:
Set one
- apple
- banana
- pear
- carrot
Set two
- banana
- peach
- plum
- apple
body {
font-family: monospace;
}
.match {
color: cornflowerblue;
font-weight: bold;
text-decoration: underline;
}
#container {
display: flex;
gap: 1rem;
justify-content: space-evenly;
}
const listOneItems = document.querySelectorAll("#set-one li");
const listTwoItems = document.querySelectorAll("#set-two li");
const allListItems = document.querySelectorAll("li");
const unionList = document.getElementById("union");
// Create sets for each list
const set1 = new Set();
const set2 = new Set();
// Add list items to each set
listOneItems.forEach((item) => {
set1.add(item.textContent);
});
listTwoItems.forEach((item) => {
set2.add(item.textContent);
});
js
// Create a union of both sets
const unionSet = set1.union(set2);
// List the items in the union
unionSet.forEach((item) => {
const li = document.createElement("li");
li.textContent = item;
unionList.appendChild(li);
});
We're using the HTML textContent of each list item so we have sets of
strings, but you can see how this can be powerful if we consider that
sets can contain data types like arrays or objects.
This is helpful because we don't need any custom implementations to
remove duplicates, do equality checks, or make other comparisons.
Once we have elements in a set, we know they're all unique, and the
union method is an optimized way to make a third set of (unique)
items that appear in 'either or both' sets.
Set intersection
With set intersection, we can check what elements occur in both sets
to see what the overlap is. In this example, instead of displaying
the intersection set as a third list like we did with union above, we
can use it to highlight elements that are 'both sets only':
Set one
- apple
- banana
- pear
- carrot
- plum
Set two
- banana
- peach
- plum
- celery
- apricots
body {
font-family: monospace;
}
.match {
color: cornflowerblue;
font-weight: bold;
text-decoration: underline;
}
#container {
display: flex;
gap: 1rem;
justify-content: space-evenly;
}
const listOneItems = document.querySelectorAll("#set-one li");
const listTwoItems = document.querySelectorAll("#set-two li");
const allListItems = document.querySelectorAll("li");
// Create sets for each list
const set1 = new Set();
const set2 = new Set();
// Add list items to each set
listOneItems.forEach((item) => {
set1.add(item.textContent);
});
listTwoItems.forEach((item) => {
set2.add(item.textContent);
});
js
// Make the intersection set
const intersectionSet = set1.intersection(set2);
// Loop through lists and highlight if they're in the intersection
allListItems.forEach((item) => {
if (intersectionSet.has(item.textContent)) {
item.className = "match";
}
});
Set symmetric difference
Before we look at difference, let's look at symmetricDifference which
might sound complex, but hopefully the example below demystifies
that. What the symmetric difference does is lets us check which
elements are in either set, but not both.
Set one
- apple
- banana
- pear
- carrot
- plum
Set two
- banana
- peach
- plum
- celery
- apricots
body {
font-family: monospace;
}
.match {
color: cornflowerblue;
font-weight: bold;
text-decoration: underline;
}
#container {
display: flex;
gap: 1rem;
justify-content: space-evenly;
}
const listOneItems = document.querySelectorAll("#set-one li");
const listTwoItems = document.querySelectorAll("#set-two li");
const allListItems = document.querySelectorAll("li");
// Create sets for each list
const set1 = new Set();
const set2 = new Set();
// Add list items to each set
listOneItems.forEach((item) => {
set1.add(item.textContent);
});
listTwoItems.forEach((item) => {
set2.add(item.textContent);
});
js
const setNotBoth = set1.symmetricDifference(set2);
allListItems.forEach((item) => {
if (setNotBoth.has(item.textContent)) {
item.className = "match";
}
});
If this is all new and you're struggling to understand, compare the
symmetric difference with the intersection example. You should see
that the symmetricDifference method does the opposite logical
operation of the intersection.
Set difference
With set difference, we can check which elements are in one set but
not in another. For this example, we are creating two new sets
instead of one. The first one (set1only) is created with
set1.difference(set2) and what we get back is a new set of items that
are 'set one only'. We do the same with the new set set2only to find
items that are in set two but not in the first one. For each list, we
can use the sets created with difference to highlight list items that
don't appear in the other list.
Set one
- apple
- banana
- pear
- carrot
- plum
Set two
- banana
- peach
- plum
- celery
- apricots
body {
font-family: monospace;
}
.setOneMatch {
color: cornflowerblue;
font-weight: bold;
text-decoration: underline;
}
.setTwoMatch {
color: orange;
font-weight: bold;
text-decoration: underline;
}
#container {
display: flex;
gap: 1rem;
justify-content: space-evenly;
}
const listOneItems = document.querySelectorAll("#set-one li");
const listTwoItems = document.querySelectorAll("#set-two li");
const allListItems = document.querySelectorAll("li");
// Create sets for each list
const set1 = new Set();
const set2 = new Set();
// Add list items to each set
listOneItems.forEach((item) => {
set1.add(item.textContent);
});
listTwoItems.forEach((item) => {
set2.add(item.textContent);
});
js
const set1only = set1.difference(set2);
const set2only = set2.difference(set1);
allListItems.forEach((item) => {
if (set1only.has(item.textContent)) {
item.className = "setOneMatch";
} else if (set2only.has(item.textContent)) {
item.className = "setTwoMatch";
}
});
Subset, superset, and disjoint from
The last of the new methods and concepts that we can explore are
subset, superset, and 'disjoint from' methods. By now, you're
familiar with the set operations that return new sets. The subset,
superset, and disjoint from methods don't return new sets, but a
Boolean value to indicate certain state or logical checks.
The first two we can look at are subset and superset. Instead of
highlighting list items, we have some statements or assertions like
"Set one is a subset of set two". We then add some text (TRUE /
FALSE) to the list item depending on the result of a check like if
(set1.isSupersetOf(set2)):
Subsets:
- Set one is a subset of set two
- Set two is a subset of set one
Supersets:
- Set one is a superset of set two
- Set two is a superset of set one
const listOneItems = document.querySelectorAll("#set-one li");
const listTwoItems = document.querySelectorAll("#set-two li");
const assertItems = document.querySelectorAll("#assertions li");
// subsets
const oneSubTwo = document.getElementById("1subset2");
const twoSubOne = document.getElementById("2subset1");
// supersets
const oneSupTwo = document.getElementById("1superset2");
const twoSupOne = document.getElementById("2superset1");
// Create sets
const set1 = new Set();
const set2 = new Set();
// Add list items to each set
listOneItems.forEach((item) => {
set1.add(item.textContent);
});
listTwoItems.forEach((item) => {
set2.add(item.textContent);
});
if (set2.isSubsetOf(set1)) {
twoSubOne.textContent += " [TRUE]";
} else {
twoSubOne.textContent += " [FALSE]";
}
if (set1.isSupersetOf(set2)) {
oneSupTwo.textContent += " [TRUE]";
} else {
oneSupTwo.textContent += " [FALSE]";
}
if (set2.isSupersetOf(set1)) {
twoSupOne.textContent += " [TRUE]";
} else {
twoSupOne.textContent += " [FALSE]";
}
js
if (set1.isSubsetOf(set2)) {
oneSubTwo.textContent += " [TRUE]";
} else {
oneSubTwo.textContent += " [FALSE]";
}
body {
font-family: sans-serif;
}
#container {
display: flex;
gap: 1rem;
justify-content: space-evenly;
}
li {
font-weight: bold;
}
#container ul {
border-radius: 10px;
display: flex;
gap: 2rem;
padding: 1rem;
justify-content: space-evenly;
list-style: none;
border: 1px solid black;
}
#set-one {
background-color: paleturquoise;
}
#set-two {
background-color: lightsteelblue;
}
So with subset, we can check if all the items from a set appear in
another set or not. With superset, we're doing the opposite, to see
if a set has all items from another set, plus some additional items.
The last method for us to look at is isDisjointFrom() where we can
find out if two sets have no common elements. The first and second
sets below are not disjoint from each other as they have one element
("C") in common. The third set is disjoint from the other two as it
has no items in common with either set:
Disjoint from:
- Set one is disjoint from set two
- Set two is disjoint from set three
- Set three is disjoint from set one
body {
font-family: sans-serif;
}
#container {
display: flex;
gap: 1rem;
justify-content: space-evenly;
}
li {
font-weight: bold;
}
#container ul {
border-radius: 10px;
display: flex;
gap: 2rem;
padding: 1rem;
justify-content: space-evenly;
list-style: none;
border: 1px solid black;
}
#set-one {
background-color: paleturquoise;
}
#set-two {
background-color: lightsteelblue;
}
#set-three {
background-color: lavender;
}
const listOneItems = document.querySelectorAll("#set-one li");
const listTwoItems = document.querySelectorAll("#set-two li");
const listThreeItems = document.querySelectorAll("#set-three li");
// Create sets
const set1 = new Set();
const set2 = new Set();
const set3 = new Set();
// Add list items to each set
listOneItems.forEach((item) => {
set1.add(item.textContent.trim());
});
listTwoItems.forEach((item) => {
set2.add(item.textContent.trim());
});
listThreeItems.forEach((item) => {
set3.add(item.textContent.trim());
});
// Assertions
const oneDisjointTwo = document.getElementById("1disjointFrom2");
const twoDisjointThree = document.getElementById("2disjointFrom3");
const threeDisjointOne = document.getElementById("3disjointFrom1");
if (set1.isDisjointFrom(set2)) {
oneDisjointTwo.textContent += " [TRUE]";
} else {
oneDisjointTwo.textContent += " [FALSE]";
}
if (set2.isDisjointFrom(set3)) {
twoDisjointThree.textContent += " [TRUE]";
} else {
twoDisjointThree.textContent += " [FALSE]";
}
if (set3.isDisjointFrom(set1)) {
threeDisjointOne.textContent += " [TRUE]";
} else {
threeDisjointOne.textContent += " [FALSE]";
}
Summary
I hope you enjoyed this post about Set methods and why I think sets
are an interesting concept to understand. Do you know different ways
to use these methods in real-world examples? Feel free to get in
touch with us and let me know what you think or if I've missed
something! You should be all Set for your next project, so see you
next time!
Previous Post Securing APIs: Express rate limit and slow down
Stay Informed with MDN
Get the MDN newsletter and never miss an update on the latest web
development trends, tips, and best practices.
Your email address:[ ]
[ ] I'm okay with Mozilla handling my info as explained in this
Privacy Notice
Sign Up Now
Your blueprint for a better internet.
* MDN on Mastodon
* MDN on X (formerly Twitter)
* MDN on GitHub
* MDN Blog RSS Feed
MDN
* About
* Blog
* Careers
* Advertise with us
Support
* Product help
* Report an issue
Our communities
* MDN Community
* MDN Forum
* MDN Chat
Developers
* Web Technologies
* Learn Web Development
* MDN Plus
* Hacks Blog
* Website Privacy Notice
* Cookies
* Legal
* Community Participation Guidelines
Visit Mozilla Corporation's not-for-profit parent, the Mozilla
Foundation.
Portions of this content are (c)1998-2024 by individual mozilla.org
contributors. Content available under a Creative Commons license.