On this page22 sections
- Prerequisites
- Connection With Previous Lectures
- Learning Objectives
- 1. Comparing Two Groups
- 2. union — Everyone in Either Set
- 3. intersection — Only the Shared Values
- 4. difference — In This One, Not That One
- 5. The Original Sets Do Not Change
- 6. containsAll — Is One Set Inside Another?
- 7. addAll, removeAll, retainAll — Change the Set Itself
- 8. where and map on a Set
- 9. Mixing Sets and Lists
- 10. A Real-World Example
- Code Examples
- Common Beginner Mistakes
- Best Practices
- Mini Challenge
- Practice Questions
- Practice Answers
- Quick Revision
- Key Takeaways
- What's Next?
Lecture 48 — Set Operations
| Category | 8 — Sets & Maps |
| Lecture | 048 of 140 |
| Estimated video length | 8 min |
| Target | Dart 3.12.2 |
| Level | Beginner |
One set answers "is this value here?". Two sets answer better questions: who is in both clubs, who is in either, and what is missing. Dart answers each in one call.
Contents
Prerequisites · Connection · Objectives · Lesson · Code Examples · Common Mistakes · Best Practices · Mini Challenge · Practice Questions · Answers · Takeaways
Every error message in this lecture is real. Each one was produced by running the code shown on Dart 3.12.2, so you will recognize it when you meet it yourself.
Prerequisites
Students should already understand, from Lectures 001–047:
finalandconstvariables (Lecture 006)- arrow functions (Lecture 034)
addAllandremoveWhereon lists (Lecture 041)where,map, andtoList(Lecture 043)Set<T>literals,add,remove,contains, and removing duplicates (Lecture 047)
Connection With Previous Lectures
In Lecture 047 we asked one set one question at a time:
chess.contains('Sara');Now the school wants to know which students are in the chess club and the football club.
With only contains, we would loop over one set and check every name against the other. The
question is about two whole groups, so we need operations that work on two whole sets.
Learning Objectives
By the end of this lecture you will be able to:
- Combine two sets with
union - Find the shared values of two sets with
intersection - Find what one set has and another lacks with
difference - Check whether one set sits inside another with
containsAll - Change a set in place with
addAll,removeAll, andretainAll - Use
whereandmapon a set and turn the result back into a set - Mix sets and lists safely in these operations
- Solve everyday problems: shared friends, club members, missing items
1. Comparing Two Groups
Every operation in this lecture compares two sets, so it helps to picture them.
Analogy — draw two overlapping circles, one per club. The overlap holds the students in both. Everything inside either circle is everyone. One circle minus the overlap is "only in this club".
void main() {
Set<String> chess = {'Ali', 'Sara', 'Zayan'};
Set<String> football = {'Sara', 'Omar', 'Zayan', 'Hina'};
print(chess);
print(football);
}{Ali, Sara, Zayan}
{Sara, Omar, Zayan, Hina}We use these two clubs throughout the lesson. Sara and Zayan are in both.
2. union — Everyone in Either Set
a.union(b) returns a new set with every value from a and every value from b. A value
in both appears once, because a set never holds duplicates.
void main() {
Set<String> chess = {'Ali', 'Sara', 'Zayan'};
Set<String> football = {'Sara', 'Omar', 'Zayan', 'Hina'};
print(chess.union(football));
}{Ali, Sara, Zayan, Omar, Hina}Values from chess come first, then the new ones from football.
3. intersection — Only the Shared Values
a.intersection(b) returns a new set with only the values that are in both sets.
void main() {
Set<String> chess = {'Ali', 'Sara', 'Zayan'};
Set<String> football = {'Sara', 'Omar', 'Zayan', 'Hina'};
print(chess.intersection(football));
}{Sara, Zayan}This is the overlap of the two circles. If nothing is shared, the result is the empty set {}.
4. difference — In This One, Not That One
a.difference(b) returns the values in a that are not in b. Order matters: swapping
the sets asks a different question.
void main() {
Set<String> chess = {'Ali', 'Sara', 'Zayan'};
Set<String> football = {'Sara', 'Omar', 'Zayan', 'Hina'};
print(chess.difference(football));
print(football.difference(chess));
}{Ali}
{Omar, Hina}Read it as "chess minus football": only Ali plays chess without playing football.
5. The Original Sets Do Not Change
union, intersection, and difference build a new set and leave both originals alone.
Store the result if you need it.
void main() {
Set<String> chess = {'Ali', 'Sara', 'Zayan'};
Set<String> football = {'Sara', 'Omar'};
Set<String> everyone = chess.union(football);
print(everyone);
print(chess);
}{Ali, Sara, Zayan, Omar}
{Ali, Sara, Zayan}Because nothing changes, these three also work on const sets.
6. containsAll — Is One Set Inside Another?
a.containsAll(b) returns true when every value of b is also in a. In other words,
b is a subset of a. Dart has no separate isSubset method; containsAll is how you
ask.
void main() {
Set<String> chess = {'Ali', 'Sara', 'Zayan'};
print(chess.containsAll({'Ali', 'Zayan'}));
print(chess.containsAll({'Ali', 'Omar'}));
}true
falseTo ask "is small inside big?", write big.containsAll(small). The bigger set goes first.
7. addAll, removeAll, retainAll — Change the Set Itself
These three change the set they are called on and return nothing. They are the in-place versions of union, difference, and intersection.
void main() {
Set<String> cart = {'milk', 'bread', 'eggs'};
cart.addAll({'rice', 'milk'});
print(cart);
cart.removeAll({'bread', 'tea'});
print(cart);
cart.retainAll({'milk', 'rice', 'sugar'});
print(cart);
}{milk, bread, eggs, rice}
{milk, eggs, rice}
{milk, rice}addAll skips the duplicate 'milk'. removeAll ignores 'tea', which was never there.
retainAll keeps only the values that also appear in its argument.
| New set (originals unchanged) | Changes the set in place |
|---|---|
a.union(b) | a.addAll(b) |
a.difference(b) | a.removeAll(b) |
a.intersection(b) | a.retainAll(b) |
8. where and map on a Set
Sets have the same where and map you used on lists in Lecture 043. Both return an
Iterable (printed with round brackets), so add .toSet() to get a set back.
void main() {
Set<String> football = {'Sara', 'Omar', 'Zayan', 'Hina'};
var shortNames = football.where((name) => name.length == 4).toSet();
print(shortNames);
Set<int> marks = {80, 75, 90};
print(marks.map((mark) => mark >= 75 ? 'pass' : 'fail'));
print(marks.map((mark) => mark >= 75 ? 'pass' : 'fail').toSet());
}{Sara, Omar, Hina}
(pass, pass, pass)
{pass}Watch the last line: map can produce repeated values, and .toSet() collapses them into one.
Iterable itself is covered in Lecture 046 — Collection Features.
9. Mixing Sets and Lists
containsAll, addAll, removeAll, and retainAll accept a list as well as a set.
union, intersection, and difference need a set, so convert a list with .toSet() first.
void main() {
Set<String> pantry = {'rice', 'salt', 'oil'};
List<String> recipe = ['rice', 'oil', 'oil'];
print(pantry.containsAll(recipe));
print(pantry.union(['sugar'].toSet()));
}true
{rice, salt, oil, sugar}10. A Real-World Example
Sara has a shopping list and a set of items already at home. What must she buy, and is anything at home not on the list?
void main() {
List<String> shoppingList = ['milk', 'eggs', 'bread', 'milk', 'tea'];
Set<String> atHome = {'eggs', 'tea', 'butter'};
Set<String> needed = shoppingList.toSet();
Set<String> toBuy = needed.difference(atHome);
Set<String> alreadyHave = needed.intersection(atHome);
Set<String> extra = atHome.difference(needed);
print('To buy: $toBuy');
print('Already have: $alreadyHave');
print('Not on the list: $extra');
print('Nothing to buy: ${atHome.containsAll(needed)}');
}To buy: {milk, bread}
Already have: {eggs, tea}
Not on the list: {butter}
Nothing to buy: falseThe list's duplicate 'milk' disappears in toSet(), then each question is one operation.
Code Examples
Example 1 — Union of Two Number Sets
void main() {
Set<int> a = {1, 2, 3};
Set<int> b = {3, 4, 5};
print(a.union(b));
}{1, 2, 3, 4, 5}Example 2 — Intersection
void main() {
Set<int> a = {1, 2, 3, 4};
Set<int> b = {3, 4, 5};
print(a.intersection(b));
}{3, 4}Example 3 — Difference Both Ways
void main() {
Set<int> a = {1, 2, 3, 4};
Set<int> b = {3, 4, 5};
print(a.difference(b));
print(b.difference(a));
}{1, 2}
{5}Example 4 — Nothing in Common
void main() {
Set<String> morning = {'Ali', 'Sara'};
Set<String> evening = {'Zayan', 'Hina'};
Set<String> both = morning.intersection(evening);
print(both);
print(both.isEmpty);
}{}
trueExample 5 — Subset Check
void main() {
Set<String> skills = {'Dart', 'Git', 'SQL'};
print(skills.containsAll({'Dart', 'Git'}));
print(skills.containsAll({'Dart', 'Java'}));
}true
falseExample 6 — In-Place Changes
void main() {
Set<int> numbers = {1, 2, 3};
numbers.addAll([3, 4]);
numbers.removeAll([1]);
numbers.retainAll({2, 4, 6});
print(numbers);
}{2, 4}addAll gives {1, 2, 3, 4}, removeAll gives {2, 3, 4}, and retainAll keeps 2 and 4.
Example 7 — Common Friends
void main() {
Set<String> aliFriends = {'Sara', 'Omar', 'Hina', 'Bilal'};
Set<String> zayanFriends = {'Hina', 'Sara', 'Usman'};
Set<String> common = aliFriends.intersection(zayanFriends);
print('Common friends: $common');
print('Count: ${common.length}');
}Common friends: {Sara, Hina}
Count: 2Example 8 — Student Marks: Who Passed Both Tests?
void main() {
Set<String> passedMath = {'Ali', 'Sara', 'Zayan'};
Set<String> passedScience = {'Sara', 'Zayan', 'Omar'};
print('Passed both: ${passedMath.intersection(passedScience)}');
print('Passed at least one: ${passedMath.union(passedScience)}');
print('Math only: ${passedMath.difference(passedScience)}');
}Passed both: {Sara, Zayan}
Passed at least one: {Ali, Sara, Zayan, Omar}
Math only: {Ali}Example 9 — Shopping: Items Out of Stock
void main() {
Set<String> order = {'pen', 'notebook', 'ruler', 'eraser'};
Set<String> inStock = {'pen', 'eraser', 'stapler'};
Set<String> missing = order.difference(inStock);
print('Missing: $missing');
print('Can ship now: ${inStock.containsAll(order)}');
}Missing: {notebook, ruler}
Can ship now: falseExample 10 — Temperature: Hot Days in Both Cities
void main() {
Set<int> lahoreHot = {1, 2, 5, 6};
Set<int> karachiHot = {2, 3, 5};
Set<int> both = lahoreHot.intersection(karachiHot);
var labels = both.map((day) => 'Day $day').toSet();
print(labels);
}{Day 2, Day 5}The sets hold day numbers. intersection finds the shared days, then map turns each number
into a label.
Common Beginner Mistakes
1. Expecting union to change the set
chess.union(football); // result thrown away
print(chess); // still the old chess clubunion, intersection, and difference return a new set. Store it, or use addAll,
retainAll, or removeAll to change the set itself.
2. Reading difference backwards
a.difference(b) is "in a, not in b". To find what is missing from stock, write
order.difference(inStock), not inStock.difference(order).
3. Storing a where result in a Set variable
void main() {
Set<String> names = {'Ali', 'Sara'};
Set<String> short = names.where((n) => n.length == 3); // ✗
print(short);
}Error: A value of type 'Iterable<String>' can't be assigned to a variable of type 'Set<String>'.Add .toSet() at the end.
4. Passing a list to union
void main() {
Set<String> names = {'Ali'};
print(names.union(['Sara'])); // ✗
}Error: The argument type 'List<String>' can't be assigned to the parameter type 'Set<String>'.Write names.union(['Sara'].toSet()), or use addAll(['Sara']) to change names.
5. Combining sets of different types
void main() {
Set<int> ids = {1, 2};
Set<String> names = {'Ali'};
print(ids.union(names)); // ✗
}Error: The argument type 'Set<String>' can't be assigned to the parameter type 'Set<int>'.6. Changing a const set in place
void main() {
const Set<String> days = {'Mon', 'Tue'};
days.addAll({'Wed'}); // ✗ compiles, then crashes
}Unhandled exception:
Unsupported operation: Cannot change an unmodifiable setUse final for a set you will change. union on a const set is fine.
7. Putting the sets the wrong way round in containsAll
big.containsAll(small) asks whether small is inside big. Swapping them asks the opposite.
Best Practices
- Name results by their meaning:
common,toBuy,missing, notresult. - Use
union/intersection/differencewhen you still need the originals. - Use
addAll/retainAll/removeAllwhen the set should really change. - Read
a.difference(b)aloud as "a minus b" before you run it. - End
whereandmapwith.toSet()when you need a set back. - Convert a list with
.toSet()before comparing it with a set.
Mini Challenge
Ali's class enrolled {'Ali', 'Sara', 'Zayan', 'Omar'}. Today's attendance list was
['Sara', 'Ali', 'Sara', 'Hina'] (Sara was scanned twice, and Hina is a visitor). Print who
was absent, who attended, and who attended without being enrolled.
Absent: {Zayan, Omar}
Attended: {Ali, Sara}
Visitors: {Hina}Try it yourself before opening the solution.
Show solution
void main() {
Set<String> enrolled = {'Ali', 'Sara', 'Zayan', 'Omar'};
Set<String> present = ['Sara', 'Ali', 'Sara', 'Hina'].toSet();
print('Absent: ${enrolled.difference(present)}');
print('Attended: ${enrolled.intersection(present)}');
print('Visitors: ${present.difference(enrolled)}');
}Absent: {Zayan, Omar}
Attended: {Ali, Sara}
Visitors: {Hina}Practice Questions
Work through these in order — they run from beginner to application to challenge. Every question gives you exact values, so you can compare your output with the answers.
Beginner
- Print the union of
{1, 2, 3}and{2, 3, 4}. - Print the intersection of
{'red', 'blue', 'green'}and{'blue', 'yellow', 'green'}. - Print
{10, 20, 30, 40}minus{20, 40}.
Application
- Sara knows
{'Dart', 'Git'}; a job needs{'Dart', 'Git', 'SQL'}. Print whether she has every required skill, then print the skills she is missing. - Start with
final tags = {'news', 'sport'}. UseaddAllwith the list['sport', 'tech'], then printtags. - Start with
final cart = {'pen', 'ink', 'pad', 'tape'}. Remove{'ink', 'tape'}in place, then printcart. - From
{45, 80, 62, 90, 30}keep only marks of 50 or more usingwhere, as a set, and print it. - Ali's friends are
{'Sara', 'Omar', 'Hina'}and Zayan's are{'Hina', 'Usman', 'Sara'}. Print their common friends and how many there are, asCommon: … (2).
Challenge
- Map the set
{3, 7, 8, 10}to'odd'or'even'and print the result as a set. - A recipe needs
['flour', 'sugar', 'eggs', 'sugar']. The kitchen has{'flour', 'salt', 'eggs'}. PrintTo buy: …, thenUnused: …for items in the kitchen the recipe does not need.
Practice Answers
Question 1 — Solution
void main() {
print({1, 2, 3}.union({2, 3, 4}));
}{1, 2, 3, 4}Question 2 — Solution
void main() {
Set<String> a = {'red', 'blue', 'green'};
Set<String> b = {'blue', 'yellow', 'green'};
print(a.intersection(b));
}{blue, green}Question 3 — Solution
void main() {
print({10, 20, 30, 40}.difference({20, 40}));
}{10, 30}Question 4 — Solution
void main() {
Set<String> sara = {'Dart', 'Git'};
Set<String> job = {'Dart', 'Git', 'SQL'};
print(sara.containsAll(job));
print(job.difference(sara));
}false
{SQL}Question 5 — Solution
void main() {
final tags = {'news', 'sport'};
tags.addAll(['sport', 'tech']);
print(tags);
}{news, sport, tech}Question 6 — Solution
void main() {
final cart = {'pen', 'ink', 'pad', 'tape'};
cart.removeAll({'ink', 'tape'});
print(cart);
}{pen, pad}Question 7 — Solution
void main() {
Set<int> marks = {45, 80, 62, 90, 30};
Set<int> passed = marks.where((mark) => mark >= 50).toSet();
print(passed);
}{80, 62, 90}Question 8 — Solution
void main() {
Set<String> ali = {'Sara', 'Omar', 'Hina'};
Set<String> zayan = {'Hina', 'Usman', 'Sara'};
Set<String> common = ali.intersection(zayan);
print('Common: $common (${common.length})');
}Common: {Sara, Hina} (2)The order follows ali, the set intersection was called on.
Question 9 — Solution
void main() {
Set<int> numbers = {3, 7, 8, 10};
print(numbers.map((n) => n % 2 == 0 ? 'even' : 'odd').toSet());
}{odd, even}Four numbers give four labels, but only two different ones survive toSet().
Question 10 — Solution
void main() {
Set<String> needed = ['flour', 'sugar', 'eggs', 'sugar'].toSet();
Set<String> kitchen = {'flour', 'salt', 'eggs'};
print('To buy: ${needed.difference(kitchen)}');
print('Unused: ${kitchen.difference(needed)}');
}To buy: {sugar}
Unused: {salt}Quick Revision
- What does
unionreturn? - Which operation finds the values two sets share?
- Why is
a.difference(b)usually different fromb.difference(a)? - How do you check that one set is a subset of another?
- What is the in-place version of
intersection? - Do
unionandintersectionchange the original sets? - What does
wherereturn on a set, and how do you get a set back? - Why can
map(...).toSet()have fewer values than the original set?
Key Takeaways
union= everything in either set;intersection= only what both share.a.difference(b)= inabut not inb; the order of the sets matters.- These three return a new set and leave the originals unchanged.
big.containsAll(small)checks whethersmallis a subset ofbig.addAll,removeAll, andretainAllchange the set itself and return nothing.whereandmapreturn anIterable; add.toSet()to get a set.union,intersection, anddifferenceneed a set — convert lists with.toSet().- A
constset cannot be changed in place; usefinalfor sets that change.
What's Next?
Lecture 049 — Maps. Sets tell us who is in a group, but not anything about them. Sara is in the chess club — what is her rating? Next we meet maps, which store each key together with a value, such as a name with a mark or a product with its price.