Skip to main content

Swift Set Operations

Introduction

Sets in Swift are unordered collections of unique values. What makes sets particularly powerful are the mathematical operations you can perform on them. These operations allow you to efficiently compare and combine sets in ways that would be cumbersome with arrays.

In this tutorial, we'll explore Swift's built-in set operations:

  • Union
  • Intersection
  • Subtraction
  • Symmetric difference

We'll learn what each operation means, how to use it in Swift, and explore practical real-world applications.

What are Set Operations?

Set operations are methods that work with two or more sets to produce new sets based on the relationship between the elements. Think of them as mathematical functions applied to collections.

Let's start by creating some example sets to work with throughout this tutorial:

swift
let programmers = Set(["Alice", "Bob", "Charlie", "Diana"])
let designers = Set(["Bob", "Eve", "Frank", "Diana"])
let managers = Set(["Charlie", "Grace", "Hannah"])

Union Operation

The union operation combines all elements from two sets into a single set. Any duplicates are automatically removed (as sets only contain unique elements).

Syntax

Swift provides two ways to create unions:

swift
// Method 1: Using the union() method
let result1 = setA.union(setB)

// Method 2: Using the union operator (∪)
let result2 = setA.formUnion(setB) // Modifies setA

Example

Let's find all people in our organization:

swift
let allEmployees = programmers.union(designers).union(managers)
print(allEmployees)
// Output: ["Diana", "Alice", "Hannah", "Bob", "Frank", "Grace", "Charlie", "Eve"]
// Note: Order may vary as sets are unordered

You can also use the formUnion method to modify a set in place:

swift
var teamMembers = programmers
teamMembers.formUnion(designers)
print(teamMembers)
// Output: ["Diana", "Alice", "Bob", "Frank", "Charlie", "Eve"]

Intersection Operation

The intersection operation creates a new set containing only the elements that appear in both sets.

Syntax

swift
// Method 1: Using the intersection() method
let result1 = setA.intersection(setB)

// Method 2: Modifying in place
let result2 = setA.formIntersection(setB) // Modifies setA

Example

Let's find people who are both programmers and designers:

swift
let programmersWhoDesign = programmers.intersection(designers)
print(programmersWhoDesign)
// Output: ["Diana", "Bob"]

// Who is both a programmer and a manager?
let programmingManagers = programmers.intersection(managers)
print(programmingManagers)
// Output: ["Charlie"]

Subtraction Operation

The subtraction operation (also called set difference) creates a new set with elements that are in the first set but not in the second set.

Syntax

swift
// Method 1: Using the subtracting() method
let result1 = setA.subtracting(setB)

// Method 2: Modifying in place
let result2 = setA.subtract(setB) // Modifies setA

Example

Let's identify programmers who aren't designers:

swift
let pureCoders = programmers.subtracting(designers)
print(pureCoders)
// Output: ["Alice", "Charlie"]

// Similarly, designers who aren't programmers:
let pureDesigners = designers.subtracting(programmers)
print(pureDesigners)
// Output: ["Eve", "Frank"]

Symmetric Difference

The symmetric difference operation creates a new set with elements that are in either set but not in both.

Syntax

swift
// Method 1: Using the symmetricDifference() method
let result1 = setA.symmetricDifference(setB)

// Method 2: Modifying in place
let result2 = setA.formSymmetricDifference(setB) // Modifies setA

Example

Find people who are either programmers or designers, but not both:

swift
let eitherProgrammerOrDesigner = programmers.symmetricDifference(designers)
print(eitherProgrammerOrDesigner)
// Output: ["Alice", "Eve", "Frank", "Charlie"]

Practical Applications

Let's explore some real-world scenarios where set operations are useful:

Managing Access Permissions

Imagine a system where users have different permission levels:

swift
let admins = Set(["Alice", "Bob"])
let contentEditors = Set(["Bob", "Charlie", "Diana"])
let subscribers = Set(["Eve", "Frank", "Diana"])

// Who has any kind of access?
let allUsers = admins.union(contentEditors).union(subscribers)

// Who are admins but also edit content?
let adminEditors = admins.intersection(contentEditors)

// Who are subscribers only (no other roles)?
let pureSubscribers = subscribers.subtracting(admins.union(contentEditors))

print("All users:", allUsers)
// Output: All users: ["Frank", "Diana", "Alice", "Bob", "Charlie", "Eve"]

print("Admin-editors:", adminEditors)
// Output: Admin-editors: ["Bob"]

print("Pure subscribers:", pureSubscribers)
// Output: Pure subscribers: ["Frank", "Eve"]

Course Enrollment System

swift
let mathStudents = Set(["Alice", "Bob", "Charlie"])
let physicsStudents = Set(["Bob", "Diana", "Eve"])
let chemistryStudents = Set(["Alice", "Eve"])

// Students taking at least one science course
let scienceStudents = physicsStudents.union(chemistryStudents)

// Students taking both math and any science
let mathAndScienceStudents = mathStudents.intersection(scienceStudents)

// Students taking math but no science
let mathOnlyStudents = mathStudents.subtracting(scienceStudents)

print("Science students:", scienceStudents)
// Output: Science students: ["Diana", "Alice", "Bob", "Eve"]

print("Math & science students:", mathAndScienceStudents)
// Output: Math & science students: ["Alice", "Bob"]

print("Math only students:", mathOnlyStudents)
// Output: Math only students: ["Charlie"]

Testing Set Relations

Swift also provides methods to test relationships between sets:

swift
let setA = Set([1, 2, 3])
let setB = Set([1, 2])
let setC = Set([4, 5])

// Is setB a subset of setA? (Are all elements of B in A?)
print(setB.isSubset(of: setA)) // true

// Is setA a superset of setB? (Are all elements of B in A?)
print(setA.isSuperset(of: setB)) // true

// Do setA and setC have no elements in common?
print(setA.isDisjoint(with: setC)) // true

Performance Considerations

Set operations in Swift are highly optimized and typically run in O(n) time, where n is the size of the sets involved. This makes them much more efficient than equivalent operations on arrays when working with large collections.

For example, finding common elements between two arrays would require nested loops, resulting in O(n²) complexity, while set intersection is just O(n).

swift
// Efficient way (using sets)
let arrayA = [1, 2, 3, 4, 5]
let arrayB = [3, 4, 5, 6, 7]

let setA = Set(arrayA)
let setB = Set(arrayB)
let commonElements = setA.intersection(setB)

print(commonElements) // [3, 4, 5]

Summary

Swift's set operations provide powerful ways to manipulate and analyze collections of unique values. These operations are:

  • Union (union, formUnion): Combines all elements from both sets.
  • Intersection (intersection, formIntersection): Finds elements common to both sets.
  • Subtraction (subtracting, subtract): Removes elements of one set from another.
  • Symmetric Difference (symmetricDifference, formSymmetricDifference): Finds elements in either set but not both.

These operations are not just theoretical concepts—they have practical applications in permissions management, data analysis, and any situation where you need to compare or combine collections.

Exercises

  1. Create sets representing movies watched by three friends. Find movies that all three have watched, and movies that only one person has watched.

  2. Implement a basic tag filtering system for a blog, where articles have tags and users can filter by including or excluding specific tags.

  3. Create a dictionary where keys are departments and values are sets of employees. Write functions to find:

    • All employees in the company
    • Employees who work in multiple departments
    • Departments that have no employees in common

Additional Resources

Happy coding!



If you spot any mistakes on this website, please let me know at [email protected]. I’d greatly appreciate your feedback! :)