What a set is
An array keeps every value you put in it, repeats included. Sometimes you only care which values there are, not how many times each one came up. A Set is built for that: it holds each value once, and inserting a value that is already there changes nothing.
var pets = Set<String>()
pets.insert("cat")
pets.insert("dog")
pets.insert("cat")
print(pets.count)
print(pets.contains("dog"))
This prints:
2
true
The basics
Set<String>()makes an empty set of strings.s.insert(x)putsxin the sets.s.contains(x)istruewhenxis in the set.s.countis the number of values it holds.Set(array)builds a set from an array, and the repeats go in once.
Checking contains on a set is fast, even for a big set. An array's contains looks at the values one by one until it finds a match.
Swift traps
- A set you change needs
var.inserton aletset is a compile error. - Brackets alone make an array.
["cat", "dog"]is an array. Wrap it,Set(["cat", "dog"]), to get a set. - No order and no index. A set has no first element and no
s[0]. A printed set may show its values in any order, and the order can change between runs. insertreturns a result. It gives back a tuple saying whether the value was new, for example(inserted: false, memberAfterInsert: "Ava")for a repeat. You can ignore it, and the compiler doesn't complain.
More ways to make and use a set
Any collection of hashable values can become a set. A string works too, and its characters become the values: Set("hello") holds 4 characters, because the two l letters collapse into one. A set can also be written as a literal when you give the type: var empty: Set<Int> = [] is an empty set of integers, and after empty.insert(4) its isEmpty is false.
Going the other way, Array(kids) turns a set back into an array. The values come out in no fixed order, so call kids.sorted() when you want them in a predictable order. For the names in this lesson, kids.sorted() gives ["Ava", "Leo", "Mia"].
When to choose a set
Pick a set when the question is "is this value in the group?" or "which different values are there?". Pick an array when the order or the repeats matter. For the camp sign-up, the array names answers "who signed up, in what order, how many times", while the set kids answers "which kids are coming". Both names.contains("Mia") and kids.contains("Mia") give true, but on a large collection the set answers far faster.
The lesson's exercise
The camp's sign-up array has some names twice:
let names = ["Ava", "Leo", "Ava", "Mia", "Leo"]
The task has three parts.
- Build a set from the array.
var kids = Set(names)keeps Ava and Leo once each, sokidsholds 3 names. It is declared withvarbecause the next step adds to it. - Add two names.
kids.insert("Zoe")grows the set to 4.kids.insert("Ava")changes nothing, because Ava is already in. - Check for Leo.
if kids.contains("Leo")is true, so the program printsLeo is coming.
Together:
var kids = Set(names)
print("\(kids.count) kids")
kids.insert("Zoe")
kids.insert("Ava")
print("\(kids.count) kids")
if kids.contains("Leo") {
print("Leo is coming")
}
The output is:
3 kids
4 kids
Leo is coming
The array names has 5 entries, but the set has 3, since a set counts different values and not entries.
Key takeaways
- A set holds each value once; inserting a repeat does nothing.
Set(array)removes repeats in one step.containson a set is fast, so use a set for "have I seen this?" questions.- Declare a set you change with
var, and don't rely on its order.
