Collections and functions

Swift Sets

Learn how to use sets in Swift to store unique, unordered items, from insert and contains to count, plus set math like union and intersection.

This tutorial belongs to the Swift series

A set is a collection of unique items.

An array can hold the same value many times. A set can’t. Insert 2 twice and it’s still there once.

You declare a set of Int values like this:

let set: Set<Int> = [1, 2, 3]

The square brackets look like an array literal, so the Set<Int> type annotation is what tells Swift you want a set. Without it you’d get an array.

Or you can build a set from an array:

let set = Set([1, 2, 3])

Adding and removing items

insert() adds an item:

var set = Set([1, 2, 3])
set.insert(17)

Insert a value that’s already there and nothing changes. That’s the whole point of a set: you never have to check for duplicates yourself.

remove() takes the value to remove, not an index, because a set has no indexes:

var set = Set([1, 2, 3])
set.remove(1)
// set is [2, 3]

removeAll() empties it:

set.removeAll()

No order

Unlike arrays, a set has no order and no positions. When you print a set, the items can come out in any sequence, and that sequence can change between runs.

When you need the items in order, turn the set into a sorted array with sorted():

var set = Set([2, 1, 3])
let orderedList = set.sorted() // [1, 2, 3]

Checking and counting

contains() tells you if a value is in the set:

var set = Set([1, 2, 3])
set.contains(2) // true

This is fast even with thousands of items, much faster than the same check on an array. If you need lots of “is this in there?” checks, use a set.

count gives you the number of items:

let set = Set([1, 2, 3])
set.count // 3

And isEmpty is true when there are none:

let set = Set([1, 2, 3])
set.isEmpty // false

Set math

Sets shine when you combine them. Say you have the tags on two blog posts:

let post1 = Set(["swift", "ios", "xcode"])
let post2 = Set(["swift", "server", "linux"])

post1.intersection(post2) // ["swift"]
post1.union(post2).count  // 5
post1.subtracting(post2)  // ["ios", "xcode"]

intersection(_:) gives the items in both. union(_:) merges them, without duplicates. subtracting(_:) gives what’s in the first but not in the second.

The full list of operations:

  • intersection(_:)
  • symmetricDifference(_:)
  • union(_:)
  • subtracting(_:)
  • isSubset(of:)
  • isSuperset(of:)
  • isStrictSubset(of:)
  • isStrictSuperset(of:)
  • isDisjoint(with:)

Sets, like arrays, are value types: pass one to a function or return it, and Swift copies it.

Sets are collections, so you can loop over them with for-in. Just don’t rely on the order you get.

Lesson completed