Dictionaries & Sets

Reviewed & published by Brayan K

Two more essential collections. By the end of this lesson you'll map keys to values with [K: V] dictionaries (handling optional lookups safely), and use Set for unique values and fast membership tests.

Part of the free Swift course at LearnCodingFast — hands-on lessons with worked examples and the output they print, plus practice exercises and a quick quiz.

What You'll Learn in This Lesson

1️⃣ Dictionaries: Key → Value

A dictionary maps unique keys to values, written [Key: Value]. Add or update with subscript assignment. Crucially, looking up a key returns an optional — it's nil when the key isn't present.

// A DICTIONARY maps KEYS to VALUES. Type: [Key: Value].
var ages: [String: Int] = ["Ann": 30, "Ben": 25]

// Add or update with subscript assignment.
ages["Cara"] = 28              // add a new pair
ages["Ann"] = 31              // update an existing key
print(ages.count)             // 3

// Looking up a key returns an OPTIONAL (the key might not exist).
let bensAge = ages["Ben"]      // Optional(25)
print(bensAge ?? -1)           // 25

let unknown = ages["Zed"]      // nil — no such key
print(unknown ?? -1)           // -1

// Provide a default inline with the subscript:
print(ages["Zed", default: 0]) // 0

Unwrap lookups safely and iterate over pairs:

// Safely unwrap a lookup with if let.
let ages = ["Ann": 30, "Ben": 25]
if let a = ages["Ann"] {
    print("Ann is \(a)")       // Ann is 30
} else {
    print("No entry for Ann")
}

// Iterate over (key, value) pairs (order is NOT guaranteed).
for (name, age) in ages.sorted(by: { $0.key < $1.key }) {
    print("\(name): \(age)")
}

// Just the keys, or just the values:
print(ages.keys.sorted())      // ["Ann", "Ben"]

// Remove a pair:
var mutable = ages
mutable["Ann"] = nil           // assigning nil removes the key
print(mutable.count)           // 1

2️⃣ Sets: Unique & Unordered

A Set<Element> stores each value at most once, with no order. Inserting a duplicate does nothing, which makes sets ideal for de-duplicating and fast contains checks.

// A SET stores UNIQUE, UNORDERED values. Type: Set<Element>.
var tags: Set<String> = ["swift", "ios", "swift"]
print(tags.count)              // 2  — the duplicate "swift" collapses

tags.insert("xcode")           // add
print(tags.contains("ios"))    // true
tags.remove("ios")             // remove
print(tags.contains("ios"))    // false

// Sets are perfect for de-duplicating an array:
let numbers = [1, 2, 2, 3, 3, 3]
let unique = Set(numbers)
print(unique.count)            // 3

3️⃣ Set Operations

Sets support clean algebra: union (everything), intersection (in both), subtracting (in one but not the other), and symmetricDifference (in exactly one).

// Set algebra: combine and compare sets.
let a: Set = [1, 2, 3, 4]
let b: Set = [3, 4, 5, 6]

print(a.union(b).sorted())            // [1, 2, 3, 4, 5, 6] — everything
print(a.intersection(b).sorted())     // [3, 4]             — in BOTH
print(a.subtracting(b).sorted())      // [1, 2]             — in a, not b
print(a.symmetricDifference(b).sorted()) // [1, 2, 5, 6]    — in exactly one

// Membership and subset checks:
print(a.contains(2))                  // true
print(Set([1, 2]).isSubset(of: a))    // true

Your turn. Fill in the blanks, then run it and check the output.

// 🎯 YOUR TURN — replace each ___ then run it in SwiftFiddle.

// 1) A dictionary mapping fruit name -> price.
var prices: [String: ___] = ["apple": 1, "pear": 2]   // 👉 value type is Int

// 2) Add a new entry: banana costs 3.
prices["banana"] = ___                                 // 👉 the number 3

// 3) Safely print the price of "pear" with a default of 0.
print(prices["pear", ___: 0])                          // 👉 replace ___ with default

// 4) A set of three colours with one duplicate — print the count.
let colours: Set = ["red", "red", "blue"]
print(colours.___)                                     // 👉 replace ___ with count

// ✅ Expected output:
//    2
//    2

Pro Tips

Common Errors (and the fix)

📋 Quick Reference

TaskCodeResult
Dictionaryvar d: [String: Int] = [:]empty map
Set / updated["a"] = 1add/update key
Lookupd["a"]Int? (optional)
Defaultd["a", default: 0]0 if missing
Setvar s: Set = [1, 2]unique values
Memberships.contains(1)true / false

Mini-Challenge: Vote Counter

Build it, run it, and check your output against the example in the comments.

// 🎯 MINI-CHALLENGE: Vote counter
// 1. Make a var dictionary 'votes' of type [String: Int], starting empty.
// 2. Given let ballots = ["cat", "dog", "cat", "cat", "dog"], loop over it and
//    count each: votes[name, default: 0] += 1
// 3. Print each candidate and their tally (sort by key for stable output).
// 4. Make a Set from ballots and print how many UNIQUE options there were.
//
// ✅ Example output:
//    cat: 3
//    dog: 2
//    unique options: 2

// your code here

🎉 Lesson Complete!

Practice quiz

How do you write the type of a dictionary mapping String keys to Int values?

  • [String, Int]
  • Dictionary(String, Int)
  • [String: Int]
  • {String: Int}

Answer: [String: Int]. Swift dictionary types are written [Key: Value], e.g. [String: Int].

What does looking up a value by key, like dict["x"], return?

  • An optional (Value?) — nil if the key is absent
  • The value directly
  • Always nil
  • A Bool

Answer: An optional (Value?) — nil if the key is absent. Subscripting by key returns an optional because the key may not exist.

Why does dictionary key lookup return an optional?

  • For speed
  • To save memory
  • It doesn't — it returns the value
  • Because the key might not be present

Answer: Because the key might not be present. A missing key yields nil, so the result type is Value?.

What kind of collection is a Set?

  • An ordered list with duplicates
  • An unordered collection of unique values
  • A key-value map
  • A fixed-size array

Answer: An unordered collection of unique values. A Set stores unique, unordered elements.

What happens if you insert a value already in a Set?

  • It has no effect — sets keep values unique
  • It's added again (duplicate)
  • The set is cleared
  • It crashes

Answer: It has no effect — sets keep values unique. Sets ignore duplicate insertions, keeping each value only once.

How do you write the type of a Set of Strings?

  • [String]
  • {String}
  • Set<String>
  • Set[String]

Answer: Set<String>. A set type is written Set<Element>, e.g. Set<String>.

Which Set method tests membership?

  • set.has(x)
  • set.contains(x)
  • set.includes(x)
  • set.member(x)

Answer: set.contains(x). contains(_:) returns a Bool indicating membership.

What does the intersection of two sets contain?

  • All elements from both
  • Elements in the first but not the second
  • Nothing
  • Only elements present in BOTH sets

Answer: Only elements present in BOTH sets. intersection keeps only the elements common to both sets.

Are the elements of a Set guaranteed to be in a particular order?

  • Yes, insertion order
  • No — a Set is unordered
  • Yes, sorted order
  • Yes, reverse order

Answer: No — a Set is unordered. Sets are unordered; iteration order is not guaranteed.

How do you safely provide a default when a dictionary key is missing?

  • dict["k"]!
  • dict.get("k")
  • dict["k", default: 0]
  • dict["k"].orElse(0)

Answer: dict["k", default: 0]. Subscript with a default: dict["k", default: 0] returns 0 if the key is absent.

Continue this course

Frequently asked questions

Why does reading dict[key] give me an optional?

Because the key might not be in the dictionary. Swift can't return a real value when nothing is stored for that key, so the subscript returns Value? — it's nil when the key is absent. Unwrap it with if let, supply a fallback with ??, or use the dict[key, default: x] form to get a non-optional with a default.

What is the difference between an array and a set?

An array is an ordered list that can contain duplicates and is accessed by integer index. A set is an unordered collection of unique values with no indexes — its strength is fast membership testing (contains) and automatically discarding duplicates. Choose a set when order doesn't matter and uniqueness does.

How do I remove a key from a dictionary?

Assign nil to it: dict[key] = nil removes the pair entirely. Alternatively call dict.removeValue(forKey: key), which also returns the removed value (as an optional) if you need it. Setting a key to a real value instead adds or updates that pair.

How can I get the unique elements of an array?

Wrap the array in a Set: let unique = Set(myArray). The set automatically collapses duplicates. If you need an array back (for example to keep working with indexes), convert again with Array(Set(myArray)) — though note the resulting order is not guaranteed.

What do union, intersection, and subtracting do?

These are set operations. union(b) returns all elements in either set; intersection(b) returns only elements present in both; subtracting(b) returns elements in the first set that are not in the second; and symmetricDifference(b) returns elements in exactly one of the two. They make comparing collections concise and readable.

Related lessons