Swift Collections: Arrays, Dictionaries, and Sets Explained


Imagine trying to keep track of every character in a Pixar movie using individual variables — character1, character2, character3… by the time you reach the entire cast of Finding Nemo, you’d have dozens of variables and no way to loop through them. Collections solve this problem by letting you group related values into a single container.

In this guide, you’ll master Swift’s three collection types: Arrays, Dictionaries, and Sets. We won’t cover advanced topics like higher-order functions or custom collections — those have their own posts.

This guide assumes you’re comfortable with data types and variables and constants.

What You’ll Learn

What Are Collections?

A collection is a container that holds multiple values in one place. Instead of creating separate variables for each Pixar movie in your list, you store them all in a single collection.

Think of it this way: if a variable is a single toy in Andy’s room, a collection is the whole toy box. You can add toys, remove them, search through them, or count how many you have — all from one place.

Swift gives you three built-in collection types:

  • Array — An ordered list. Items have positions (indices).
  • Dictionary — A lookup table. Values stored by unique keys.
  • Set — An unordered bag of unique items. No duplicates.

Arrays

An Array stores values in an ordered list. Each value has a position called an index, starting at 0. Arrays allow duplicate values.

Creating Arrays

let movies = ["Toy Story", "Finding Nemo", "Up"]
let ratings: [Double] = [8.3, 8.2, 8.3]
var emptyList: [String] = []

The first array uses type inference — Swift figures out it’s [String] from the values. The second uses an explicit type annotation. The third creates an empty array that will hold strings.

Accessing Elements

Use the index to read a value. Remember: the first item is at index 0, not 1.

let movies = ["Toy Story", "Finding Nemo", "Up"]
print(movies[0])
print(movies[2])
print(movies.count)
Toy Story
Up
3

Warning: Accessing an index that doesn’t exist — like movies[5] on a 3-element array — will crash your app. Always check count first or use safe methods.

Adding and Removing

Use var to create a mutable array, then modify it:

var characters = ["Woody", "Buzz"]
characters.append("Jessie")
characters.insert("Rex", at: 1)
print(characters)
["Woody", "Rex", "Buzz", "Jessie"]

To remove items:

var characters = ["Woody", "Rex", "Buzz", "Jessie"]
characters.remove(at: 1)
print(characters)
["Woody", "Buzz", "Jessie"]

Checking Contents

let movies = ["Toy Story", "Up", "Coco"]
print(movies.contains("Coco"))
print(movies.isEmpty)
print(movies.first ?? "No movies")
true
false
Toy Story

The first property returns an optional — it’s nil if the array is empty. The ?? provides a default value.

Dictionaries

A Dictionary stores key-value pairs. Instead of looking up values by position, you look them up by a unique key. Order is not guaranteed.

Creating Dictionaries

let movieYears: [String: Int] = [
    "Toy Story": 1995,
    "Finding Nemo": 2003,
    "Inside Out": 2015
]

The type [String: Int] means the keys are strings and the values are integers.

Accessing Values

When you look up a key, Swift returns an optional because the key might not exist:

let movieYears = [
    "Toy Story": 1995,
    "Finding Nemo": 2003
]
let year = movieYears["Toy Story"]
print(year ?? "Unknown")

let missing = movieYears["Cars"]
print(missing ?? "Unknown")
1995
Unknown

Note: Dictionary lookups always return an optional. Use ?? to provide a default value, or unwrap safely with if let.

Adding, Updating, and Removing

var directors: [String: String] = [:]
directors["Toy Story"] = "John Lasseter"
directors["Up"] = "Pete Docter"
print(directors)

directors["Toy Story"] = "Updated Director"
directors["Up"] = nil  // Removes the entry
print(directors)
["Up": "Pete Docter", "Toy Story": "John Lasseter"]
["Toy Story": "Updated Director"]

Setting a key to nil removes that entry from the dictionary.

Iterating Over a Dictionary

let scores = ["Woody": 95, "Buzz": 88, "Rex": 72]
for (character, score) in scores {
    print("\(character): \(score)")
}
Woody: 95
Buzz: 88
Rex: 72

Note: The order of items when iterating a dictionary is not guaranteed. If you need a specific order, sort the keys first or use an array instead.

Sets

A Set stores unique values with no defined order. If you try to add a duplicate, the set simply ignores it.

Creating Sets

let genres: Set<String> = ["Animation", "Comedy", "Family"]
let numbers: Set = [1, 2, 3, 3, 3]
print(numbers)
[1, 3, 2]

Notice that even though we added three 3s, the set only keeps one. The printed order may vary because sets are unordered.

Adding and Removing Set Elements

var tags: Set = ["Pixar", "Animation"]
tags.insert("Comedy")
tags.remove("Animation")
print(tags)
print(tags.contains("Pixar"))
["Pixar", "Comedy"]
true

Set Operations

Sets excel at comparing groups. Think of it like comparing the cast lists of two Pixar movies:

let toyStory: Set = ["Woody", "Buzz", "Rex", "Hamm"]
let toyStory2: Set = ["Woody", "Buzz", "Jessie", "Bullseye"]

print(toyStory.intersection(toyStory2))
print(toyStory.union(toyStory2))
print(toyStory.subtracting(toyStory2))
["Woody", "Buzz"]
["Woody", "Buzz", "Rex", "Hamm", "Jessie", "Bullseye"]
["Rex", "Hamm"]
  • intersection — items in both sets
  • union — all items from either set
  • subtracting — items in the first but not the second

Apple Docs: Set — Swift Standard Library

Choosing the Right Collection

NeedUseWhy
Ordered list with duplicatesArrayPosition matters
Look up values by keyDictionaryFast key-based access
Unique values, no order neededSetAutomatic deduplication
Check membership frequentlySetcontains is very fast

Tip: Start with an Array when you’re unsure. It’s the most common collection type and works for most situations. Switch to a Dictionary or Set when you have a specific need.

Mutability: var vs let

Collections follow the same mutability rules as regular values. A let collection cannot be changed after creation:

let fixedMovies = ["Toy Story", "Cars"]
// fixedMovies.append("Up")  // ❌ Won't compile

var flexibleMovies = ["Toy Story", "Cars"]
flexibleMovies.append("Up")  // ✅ Works fine
print(flexibleMovies)
["Toy Story", "Cars", "Up"]

This applies to all three collection types — arrays, dictionaries, and sets.

Common Mistakes

Accessing Out-of-Bounds Array Indices

// ❌ Don't do this — crashes at runtime
let movies = ["Up", "Coco"]
// let third = movies[2]
// ✅ Check the count first
let movies = ["Up", "Coco"]
if movies.count > 2 {
    print(movies[2])
} else {
    print("Only \(movies.count) movies")
}
Only 2 movies

Forgetting Dictionary Values Are Optionals

// ❌ This won't compile without handling the optional
let years = ["Up": 2009]
// let result: Int = years["Up"]
// ✅ Unwrap the optional safely
let years = ["Up": 2009]
if let year = years["Up"] {
    print("Released in \(year)")
}
Released in 2009

Expecting Sets to Preserve Order

// ❌ Don't rely on set order
let steps: Set = ["Step 1", "Step 2", "Step 3"]
// Might print in any order!

// ✅ Use an array when order matters
let steps = ["Step 1", "Step 2", "Step 3"]
for step in steps {
    print(step)
}
Step 1
Step 2
Step 3

What’s Next?

  • Arrays store ordered lists and allow duplicates
  • Dictionaries store key-value pairs with fast lookups
  • Sets store unique values with powerful comparison operations
  • Use var for mutable collections, let for fixed ones
  • Dictionary lookups return optionals — always unwrap safely

Now that you can group values together, you need to make decisions based on those values. Head over to Control Flow in Swift to learn about if, switch, and guard.