DEV Community

Gamya
Gamya

Posted on

Swift Sets

We've covered arrays and dictionaries — two of the most common ways to store data in Swift. But there's a third collection type that doesn't get enough love: sets.

At first glance, sets look a lot like arrays. But under the hood they're built very differently — and knowing when to use one can make your code dramatically faster ⚡


📦 What Is a Set?

A set is a collection of values — just like an array — but with two key rules:

  • No duplicates allowed
  • No guaranteed order

That's it. Those two constraints sound like limitations, but they're actually what give sets their superpowers — more on that in a moment.


🆚 Array vs Set — Side by Side

Array Set
Allows duplicates ✅ Yes ❌ No
Keeps order ✅ Yes ❌ No
Fast lookup with contains() ❌ Slow ✅ Blazing fast
Add items with .append() .insert()
Best for Ordered lists Unique values & fast search

🏗️ Creating a Set

From existing values:

let akatsukiMembers = Set(["Itachi", "Kisame", "Pain", "Konan", "Tobi"])
print(akatsukiMembers)
// Might print in any order — sets don't care!
Enter fullscreen mode Exit fullscreen mode

Notice how you first create an array, then wrap it in Set(). That's the standard way to create a set from fixed data. And if you had any duplicates in that array, the set would silently remove them for you.

Starting empty and adding items one by one:

var akatsukiMembers = Set<String>()
akatsukiMembers.insert("Itachi")
akatsukiMembers.insert("Kisame")
akatsukiMembers.insert("Pain")
akatsukiMembers.insert("Konan")
Enter fullscreen mode Exit fullscreen mode

💡 Notice we use .insert() instead of .append(). That's because .append() implies adding to the end — but sets have no end. Items go wherever the set decides is best for fast retrieval.


🔍 The Real Magic — No Duplicate Keys

Let's say you're tracking which anime a user has watched. You want to make sure each title only appears once:

var watchedAnime = Set<String>()

watchedAnime.insert("Naruto")
watchedAnime.insert("One Piece")
watchedAnime.insert("Naruto") // Already there!
watchedAnime.insert("Bleach")

print(watchedAnime.count) // 3 — not 4!
Enter fullscreen mode Exit fullscreen mode

The second "Naruto" is silently ignored. No crash, no error — the set just knows it already has it. 🧠


🎯 insert() Tells You What Happened

Here's something arrays can't do — when you insert into a set, you get back a result telling you whether the insert actually worked:

var watchedAnime: Set<String> = ["Naruto", "Bleach", "One Piece"]

let (inserted, member) = watchedAnime.insert("Naruto")

if !inserted {
    print("\(member) is already in your watch list!")
}
// Prints: Naruto is already in your watch list!
Enter fullscreen mode Exit fullscreen mode

This is super useful for giving users feedback in a real app — like telling them a show is already in their watchlist. ✅


⚡ Why Sets Are So Much Faster Than Arrays

This is the big one. Let's talk about speed.

Imagine you have a list of 10,000 anime titles stored in an array, and you want to check if "Attack on Titan" is in there:

let animeArray = ["Naruto", "One Piece", ... /* 10,000 items */]
animeArray.contains("Attack on Titan")
Enter fullscreen mode Exit fullscreen mode

Swift has to start at index [0] and check every single item one by one until it finds a match — or reaches the end. In the worst case, that's 10,000 checks. 😬

Now the same thing with a set:

let animeSet: Set<String> = ["Naruto", "One Piece", ... /* 10,000 items */]
animeSet.contains("Attack on Titan")
Enter fullscreen mode Exit fullscreen mode

Swift finds the answer instantly — no matter if there are 10,000 or 10 million items. Sets are built internally with an optimized structure that jumps straight to where the value would be, rather than scanning through everything.

🧠 Why is this possible? Because sets don't preserve order, Swift is free to store items however it wants — and it chooses a structure (called a hash table) that makes lookups nearly instant.


🔄 Order — What to Expect

let arrayVersion: [String] = ["Swift", "Xcode", "iOS", "Debugging"]
let setVersion: Set<String> = ["Swift", "Xcode", "iOS", "Debugging"]

print(arrayVersion) // ["Swift", "Xcode", "iOS", "Debugging"] — always same order
print(setVersion)   // ["iOS", "Swift", "Debugging", "Xcode"] — could be anything!
Enter fullscreen mode Exit fullscreen mode

The array always preserves the order you gave it. The set rearranges things however it sees fit. If order matters to you — use an array. If it doesn't — a set might be the smarter choice.


🛠️ Useful Set Operations

📏 Count — How many unique items?

let episodes: Set = ["Episode 1", "Episode 2", "Episode 3", "Episode 1"]
print(episodes.count) // 3 — duplicate removed automatically
Enter fullscreen mode Exit fullscreen mode

🔍 contains() — Lightning fast lookup

let powerUsers: Set = ["Goku", "Saitama", "Naruto", "Luffy"]

print(powerUsers.contains("Saitama"))  // true
print(powerUsers.contains("Shinji"))   // false
Enter fullscreen mode Exit fullscreen mode

🔤 sorted() — Get a sorted array back

let villains: Set = ["Madara", "All For One", "Aizen", "Frieza"]
print(villains.sorted())
// ["Aizen", "All For One", "Frieza", "Madara"]
Enter fullscreen mode Exit fullscreen mode

sorted() doesn't change the set — it returns a brand new sorted array from the set's contents.


🧩 Putting It All Together

Here's a practical example — a duplicate-free watched list with fast lookup:

var watchList = Set<String>()

// Add some anime
watchList.insert("Attack on Titan")
watchList.insert("Demon Slayer")
watchList.insert("Jujutsu Kaisen")
watchList.insert("Attack on Titan") // duplicate — ignored silently

// How many unique shows?
print("Watched: \(watchList.count) shows") // 3

// Already watched this?
if watchList.contains("Demon Slayer") {
    print("Already watched Demon Slayer!")
} else {
    print("Adding to list...")
}

// Show list in alphabetical order
print(watchList.sorted())
// ["Attack on Titan", "Demon Slayer", "Jujutsu Kaisen"]
Enter fullscreen mode Exit fullscreen mode

🤔 So When Should You Use a Set?

Use a set when:

  • You need to store unique values — no duplicates allowed
  • You need to check "does this exist?" very frequently and speed matters
  • The order doesn't matter to you

Use an array when:

  • Order matters — like a playlist, leaderboard, or step-by-step list
  • You need duplicate values — like tracking every time something happens
  • You need to access items by position

Most of the time you'll reach for an array — and that's completely fine. But when you need fast lookup on a unique collection, sets are the right tool for the job 🛠️


🌟 Wrap Up

Sets are simple but powerful:

  • ✅ No duplicates — enforced automatically
  • ✅ Blazing fast contains() — even with millions of items
  • insert() tells you if the item was already there
  • sorted() gives you an ordered array when you need one
  • ❌ No guaranteed order — if that matters, use an array

Arrays, dictionaries, and sets together cover almost every data storage need you'll run into as a Swift developer. Knowing which one to reach for — and why — is what separates good code from great code 💪

Next up, we'll look at enums — a powerful Swift feature for working with a fixed set of related values. See you there! 👋

Top comments (0)