DEV Community

Gamya
Gamya

Posted on

Swift Dictionaries

We've already seen how arrays let us store lots of values in one place. But arrays have a problem — you have to remember positions to get your data back.

What if there was a smarter way? 🤔

That's where dictionaries come in.


The Problem with Arrays

Let's say you're storing a character's profile from My Hero Academia:

var hero = ["Izuku Midoriya", "One For All", "Class 1-A"]
Enter fullscreen mode Exit fullscreen mode

Now to read that data back:

print("Name: \(hero[0])")
print("Quirk: \(hero[1])")
print("Class: \(hero[2])")
Enter fullscreen mode Exit fullscreen mode

This works... but it's fragile. What if someone removes an item from the array?

print("Name: \(hero[0])")
hero.remove(at: 1)
print("Quirk: \(hero[1])")   // ❌ Now prints "Class 1-A" — wrong!
print("Class: \(hero[2])")   // 💥 CRASH — index doesn't exist anymore
Enter fullscreen mode Exit fullscreen mode

Everything falls apart. You can't trust positions. You have to remember what index holds what — and that's a recipe for bugs 🐛


Enter Dictionaries

Instead of positions, dictionaries use keys — labels you choose yourself to describe exactly what each value means.

Here's the same hero profile, rewritten as a dictionary:

let hero = [
    "name": "Izuku Midoriya",
    "quirk": "One For All",
    "class": "Class 1-A"
]
Enter fullscreen mode Exit fullscreen mode

Now reading data is crystal clear:

print(hero["name", default: "Unknown"])
print(hero["quirk", default: "Unknown"])
print(hero["class", default: "Unknown"])
Enter fullscreen mode Exit fullscreen mode

No guessing. No positions. No crashes from removed items. Just clean, readable code 🌸


🔑 Keys and Values

Every item in a dictionary has two parts:

Part What it is Example
Key The label you use to find the data "name"
Value The actual data stored "Izuku Midoriya"

Think of it like a character profile card — you look up the field name (key) and get the info (value) back instantly, even if there are thousands of entries. Swift optimizes dictionaries specifically for this kind of fast lookup ⚡


⚠️ Why Dictionaries Return Optionals

Try reading a key that doesn't exist in the dictionary:

print(hero["villain"])
Enter fullscreen mode Exit fullscreen mode

Swift won't crash — but it will return nil, meaning nothing. That's because Swift can't guarantee that every key you ask for actually exists. This is why reading from a dictionary gives you back an optional value — it might be there, or it might not.

You'll see a warning like:

Expression implicitly coerced from 'String?' to 'Any'
Enter fullscreen mode Exit fullscreen mode

Swift is telling you "hey, are you sure this value exists?" 🤔

We'll cover optionals in depth later in this series — but for now, there's a simple and clean solution.


🛡️ Default Values — Your Safety Net

When reading from a dictionary, you can provide a default value that gets used if the key doesn't exist:

print(hero["name", default: "Unknown"])      // Izuku Midoriya
print(hero["villain", default: "Unknown"])   // Unknown
Enter fullscreen mode Exit fullscreen mode

No crash. No warning. Just a safe fallback value. ✅

Here's a more real-world example — tracking exam scores:

let examScores = [
    "math": 95,
    "english": 88,
    "history": 72
]

print(examScores["math", default: 0])      // 95
print(examScores["science", default: 0])   // 0 — didn't take it
Enter fullscreen mode Exit fullscreen mode

💡 When should you use a default value?

  • Use default: 0 if a missing score means the student didn't take the exam
  • Skip the default and handle nil directly if missing means they haven't taken it yet

The right choice depends on what your app needs to do with that missing data.


Different Types for Keys and Values

Dictionaries aren't limited to String keys and String values. You can mix and match types.

String keys, Bool values — tracking which characters have awakened their powers:

let awakenedPowers = [
    "Izuku": true,
    "Bakugo": true,
    "Mineta": false
]
Enter fullscreen mode Exit fullscreen mode

Integer keys, String values — tracking anime seasons by year:

let seasonYears = [
    2013: "Attack on Titan S1",
    2017: "Attack on Titan S2",
    2022: "Attack on Titan Final Season"
]

print(seasonYears[2013, default: "Unknown"])
// Attack on Titan S1
Enter fullscreen mode Exit fullscreen mode

Creating Empty Dictionaries

Just like arrays, you can start with an empty dictionary and fill it in over time.

var characterStats = [String: Int]()

characterStats["strength"] = 95
characterStats["speed"] = 88
characterStats["intelligence"] = 70
Enter fullscreen mode Exit fullscreen mode

The [String: Int] syntax means:

  • Keys will be String
  • Values will be Int

You can do the same for any type combination — [String: String], [Int: Bool], and so on.


🔄 Updating Values — No Duplicates Allowed

Dictionaries do not allow duplicate keys. If you assign a value to a key that already exists, Swift simply overwrites the old value:

var rivalry = [String: String]()

rivalry["Naruto"] = "Sasuke"
print(rivalry["Naruto", default: "Unknown"])  // Sasuke

rivalry["Naruto"] = "Pain"
print(rivalry["Naruto", default: "Unknown"])  // Pain
Enter fullscreen mode Exit fullscreen mode

The old value is gone — replaced by the new one. So every key in a dictionary is always unique. 🔒


🛠️ Useful Dictionary Operations

📏 Count — How many entries?

let heroTeam = ["leader": "Levi", "scout": "Eren", "medic": "Hange"]
print(heroTeam.count) // 3
Enter fullscreen mode Exit fullscreen mode

🗑️ Remove Everything

var tempData = ["key1": "value1", "key2": "value2"]
tempData.removeAll()
print(tempData.count) // 0
Enter fullscreen mode Exit fullscreen mode

🧩 Putting It All Together

Here's a mini character profile system using everything we covered:

// Create a character profile
var profile = [String: String]()

profile["name"] = "Levi Ackerman"
profile["rank"] = "Captain"
profile["squad"] = "Survey Corps"
profile["weapon"] = "Omni-Directional Mobility Gear"

// Read profile safely
print(profile["name", default: "Unknown"])     // Levi Ackerman
print(profile["rank", default: "Unknown"])     // Captain
print(profile["hometown", default: "Unknown"]) // Unknown

// Update a value
profile["rank"] = "Humanity's Strongest"
print(profile["rank", default: "Unknown"])     // Humanity's Strongest

// Check size
print(profile.count) // 4

// Clear everything
profile.removeAll()
print(profile.count) // 0
Enter fullscreen mode Exit fullscreen mode

🆚 Arrays vs Dictionaries — Which to Use?

Arrays Dictionaries
Access by Position (index) Label (key)
Order ✅ Preserved ❌ Not guaranteed
Duplicate items ✅ Allowed ❌ Keys must be unique
Safe access ❌ Wrong index = crash ✅ Missing key = nil
Best for Ordered lists Labelled data / lookups

🌟 Wrap Up

Dictionaries solve a real problem that arrays can't — they let you store and retrieve data using meaningful labels instead of fragile position numbers.

  • Use arrays when order matters and items are accessed by position
  • Use dictionaries when you want to look things up by name

In real apps you'll reach for dictionaries constantly — user profiles, settings, API responses, game stats, and so much more. Getting comfortable with them now will pay off big time down the road 💪

Next up, we'll look at sets — another way to store data, but with some very interesting superpowers. See you there! 👋

Top comments (0)