Start learning free

LESSON 235 OF 678 · SETS

Sets in Swift: Set, insert and contains

Lesson Read the full explanation

TL ; DR:

A Set holds values without repeats. Inserting a value that is already in it changes nothing.


var pets = Set<String>()          // an empty set
pets.insert("cat")
pets.insert("dog")
pets.insert("cat")                 // already in it, no change

print(pets.count)                  // 2
print(pets.contains("dog"))        // true


Full lesson:

An array keeps every value you put in it, repeats too. Sometimes you only need to know which values there are. A set is made for that.

A set holds each value once. Inserting a value that is already in it changes nothing.

  • Set<String>() makes an empty set of strings.
  • s.insert(x) puts x in the set s.
  • s.contains(x) is true when x is in the set.
  • s.count gives how many values the set holds.
  • Set(array) builds a set from an array. Its repeats go in once.

Checking s.contains(x) is fast, even for a big set. An array's contains looks at the values one by one.

A set you change needs var. And ["cat", "dog"] on its own is an array. Set(...) turns it into a set.

A set has no order and no number indexes. A printed set may show its values in any order.


Your task

The camp's sign-up array, names, has some names twice. Build a set named kids from it.

Then Zoe signs up, and Ava signs up again. Insert both names into kids.

Last, if kids contains "Leo", print Leo is coming.

The code already prints the number of kids twice.

Expected output:

3 kids
4 kids
Leo is coming
STEP 1 OF 3
    Ctrl + Enter to check

    SWIFT · SETS

    Sets in Swift, explained

    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) puts x in the set s.
    • s.contains(x) is true when x is in the set.
    • s.count is 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. insert on a let set 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.
    • insert returns 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.

    1. Build a set from the array. var kids = Set(names) keeps Ava and Leo once each, so kids holds 3 names. It is declared with var because the next step adds to it.
    2. Add two names. kids.insert("Zoe") grows the set to 4. kids.insert("Ava") changes nothing, because Ava is already in.
    3. Check for Leo. if kids.contains("Leo") is true, so the program prints Leo 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.
    • contains on 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.
    Keep going with Swift500+ step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free