Collections
Master Swift's Array, Set, and Dictionary collection types, mutability rules, iteration, and higher-order functions like map, filter, and reduce.
Introduction
Swift's standard library gives you three core collection types — `Array`, `Set`, and `Dictionary` — each optimized for a different job. All three are value types, meaning (like structs) assigning or passing one copies it, so mutating a copy never affects the original.
This lesson covers each collection type, common operations, mutability rules, iteration, and the higher-order functions `map`, `filter`, and `reduce` that make transforming collections concise and expressive.
Arrays
An `Array` is an ordered collection that allows duplicate values, and is the collection type you'll reach for most often.
var languages = ["Swift", "Python", "Go"]languages.append("Rust")
print(languages)print(languages[1])print(languages.count)Click Run to see what this code prints.
Common Array Operations
languages.remove(at: 0)languages.insert("Kotlin", at: 0)print(languages)print(languages.sorted())print(languages.contains("Rust"))Click Run to see what this code prints.
Sets
A `Set` stores unique, unordered values — inserting a duplicate is a no-op, and membership checks are extremely fast, making Sets ideal when you only care about "is this present" rather than order.
var uniqueTags: Set<String> = ["ios", "swift", "mobile"]uniqueTags.insert("swift") // already present — no effect
print(uniqueTags.contains("ios"))print(uniqueTags.count)Click Run to see what this code prints.
Dictionaries
A `Dictionary` stores key-value pairs, giving fast lookup by key. Accessing a key that might not exist always returns an Optional.
var scores: [String: Int] = ["Amit": 90, "Priya": 85]scores["Rahul"] = 78
print(scores["Amit"] ?? 0)
for (name, score) in scores { print("\(name): \(score)")}Click Run to see what this code prints.
Iterating Collections
All three collection types work with `for-in` loops. Arrays iterate in their stored order; Sets and Dictionaries do not guarantee any particular order between runs.
Mutability
Just like any other value, declaring a collection with `let` makes it fully immutable — you can't append, remove, or change any of its contents, not just reassign it. Declaring with `var` allows full mutation.
let fixedList = ["a", "b", "c"]// fixedList.append("d") // Compile-time error: cannot mutate a 'let' arrayHigher-Order Functions
`map`, `filter`, and `reduce` transform collections without you writing manual loops: `map` transforms every element, `filter` keeps only elements matching a condition, and `reduce` combines all elements into a single value.
let numbers = [1, 2, 3, 4, 5, 6]
let evens = numbers.filter { $0 % 2 == 0 }let squares = numbers.map { $0 * $0 }let sum = numbers.reduce(0, +)
print(evens)print(squares)print(sum)Click Run to see what this code prints.
Common Mistakes
- Assuming a Set or Dictionary preserves insertion order the way an Array does — neither guarantees any particular order.
- Trying to mutate a collection declared with `let` — the entire collection is immutable, not just protected from reassignment.
- Force-unwrapping a dictionary subscript result (`dict[key]!`) instead of using `??` or `if let` to handle a missing key safely.
- Reaching for an Array when uniqueness is what actually matters — a Set expresses that intent directly and checks membership faster.
Best Practices
- Choose Array when order matters and duplicates are fine; Set when you need uniqueness or fast membership tests; Dictionary for key-based lookup.
- Prefer `map`/`filter`/`reduce` over manual `for` loops when it makes the transformation clearer, but don't force it when a simple loop reads better.
- Declare collections with `let` whenever they won't be mutated after creation, to get compiler-enforced immutability.
- Use `??` to provide defaults for dictionary lookups instead of force-unwrapping.
Frequently Asked Questions
Value types. Assigning an Array, Set, or Dictionary to a new variable, or passing it to a function, copies it (using an optimization called copy-on-write so it's efficient in practice) — mutating the copy never affects the original.
A dictionary key must conform to the `Hashable` protocol. Swift's built-in types like String, Int, and Bool already conform, and your own types can conform too.
reduce shines when you're combining a collection into a single summary value, like a sum or a concatenated string — for anything more complex, a plain for loop is often more readable.
Key Takeaways
- Array is ordered and allows duplicates; Set is unordered and unique; Dictionary maps keys to values.
- All three collection types are value types with copy-on-write semantics.
- Declaring a collection with `let` makes its entire contents immutable, not just its reference.
- map transforms elements, filter keeps matching elements, and reduce combines elements into one value.
- Dictionary subscript access always returns an Optional, since the key might not exist.
Summary
You now know how to store and transform data with Swift's core collection types. Next, you'll learn protocols and extensions — the tools behind Swift's protocol-oriented programming style.