Collection Types
Swift offers three primary collection types: arrays, sets, and dictionaries for organizing data. Arrays store ordered lists of values, sets hold unique values without order, and dictionaries manage key-value pairs without order. Each collection enforces strict type safety, ensuring values and keys are of the correct type, preventing errors and enhancing reliability.
Note
Swift’s collection types are generic, enabling flexible and reusable code. For more on generics, refer to Swift’s documentation on generics.
Mutability of Collections
Collections assigned to a variable (var
) are mutable, allowing modifications like adding or removing items. Collections assigned to a constant (let
) are immutable, with fixed size and content. Using immutable collections when possible improves code clarity and allows the Swift compiler to optimize performance.
Arrays
An array stores values of the same type in an ordered, zero-indexed list. Duplicate values are allowed at different positions.
Note
Swift’s Array
type integrates with Foundation’s NSArray
. Refer to Apple’s documentation for details on bridging.
Array Type Shorthand
Arrays are written as Array<Element>
or in shorthand as [Element]
, where Element
is the type of stored values. The shorthand [Element]
is preferred.
Creating an Empty Array
Create an empty array using an empty array literal []
when type information is clear, or with explicit initializer syntax [Element]()
:
var numbers: [Int] = []
print("Numbers is a [Int] with \(numbers.count) items.")
// Prints "Numbers is a [Int] with 0 items."
var moreNumbers = [Int]()
print("MoreNumbers is a [Int] with \(moreNumbers.count) items.")
// Prints "MoreNumbers is a [Int] with 0 items."
You can reset a mutable array to empty using []
:
numbers.append(5)
print("Numbers now has \(numbers.count) item.")
// Prints "Numbers now has 1 item."
numbers = []
print("Numbers is now empty but remains [Int].")
// Prints "Numbers is now empty but remains [Int]."
Creating an Array with a Default Value
Initialize an array with a repeated default value using the repeating:count:
initializer:
var zeros = Array(repeating: 0, count: 4)
// Zeros is [Int], equals [0, 0, 0, 0]
Combining Arrays
Combine two arrays of the same type using the +
operator:
var ones = Array(repeating: 1, count: 3)
var twos = Array(repeating: 2, count: 2)
var combined = ones + twos
// Combined is [Int], equals [1, 1, 1, 2, 2]
Creating an Array with an Array Literal
Use an array literal to initialize an array with values:
var groceryList = ["Apples", "Bread", "Milk"]
// GroceryList is [String] with 3 items
Swift infers the type if all literal values match, so [String]
can be omitted.
Accessing and Modifying Arrays
Access array properties and methods to manipulate content:
- Check the number of items with
count
:
print("Grocery list has \(groceryList.count) items.")
// Prints "Grocery list has 3 items."
- Check if empty with
isEmpty
:
if groceryList.isEmpty {
print("Grocery list is empty.")
} else {
print("Grocery list has items.")
}
// Prints "Grocery list has items."
- Append items with
append(_:)
or+=
:
groceryList.append("Eggs")
// GroceryList now has 4 items
groceryList += ["Butter", "Sugar"]
// GroceryList now has 6 items
- Access or modify items using subscript syntax:
var first = groceryList[0]
// First is "Apples"
groceryList[0] = "Green Apples"
// First item is now "Green Apples"
- Replace a range of items:
groceryList[3...5] = ["Oranges", "Bananas"]
// GroceryList now has 5 items
- Insert items with
insert(_:at:)
:
groceryList.insert("Juice", at: 1)
// GroceryList now has 6 items, with "Juice" at index 1
- Remove items with
remove(at:)
orremoveLast()
:
let removed = groceryList.remove(at: 1)
// Removed is "Juice", GroceryList has 5 items
let last = groceryList.removeLast()
// Last is "Bananas", GroceryList has 4 items
Note
Accessing an invalid index causes a runtime error. Always ensure the index is less than count
.
Iterating Over an Array
Use a for-in
loop to iterate over array elements:
for item in groceryList {
print(item)
}
// Green Apples
// Bread
// Milk
// Oranges
Use enumerated()
to access both index and value:
for (index, item) in groceryList.enumerated() {
print("Item \(index + 1): \(item)")
}
// Item 1: Green Apples
// Item 2: Bread
// Item 3: Milk
// Item 4: Oranges
Sets
A set stores unique values of the same type without order. Use sets when order doesn’t matter or to ensure uniqueness.
Note
Swift’s Set
type integrates with Foundation’s NSSet
. Check Apple’s documentation for bridging details.
Hash Values for Sets
Set elements must conform to the Hashable
protocol, providing a consistent Int
hash value for equal objects. Swift’s basic types (String
, Int
, Double
, Bool
) and enum cases without associated values are hashable by default.
Set Type Syntax
Sets are written as Set<Element>
, with no shorthand form.
Creating an Empty Set
Initialize an empty set with Set<Element>()
:
var colors = Set<String>()
print("Colors is Set<String> with \(colors.count) items.")
// Prints "Colors is Set<String> with 0 items."
Reset a mutable set to empty using []
:
colors.insert("Blue")
// Colors has 1 item
colors = []
// Colors is empty, still Set<String>
Creating a Set with an Array Literal
Initialize a set with an array literal:
var hobbies: Set = ["Reading", "Gaming", "Hiking"]
// Hobbies is Set<String> with 3 items
Accessing and Modifying Sets
- Check size with
count
:
print("I have \(hobbies.count) hobbies.")
// Prints "I have 3 hobbies."
- Check if empty with
isEmpty
:
if hobbies.isEmpty {
print("No hobbies.")
} else {
print("I have hobbies.")
}
// Prints "I have hobbies."
- Add items with
insert(_:)
:
hobbies.insert("Cooking")
// Hobbies now has 4 items
- Remove items with
remove(_:)
orremoveAll()
:
if let removed = hobbies.remove("Gaming") {
print("Removed \(removed).")
} else {
print("Gaming not found.")
}
// Prints "Removed Gaming."
- Check membership with
contains(_:)
:
if hobbies.contains("Reading") {
print("Love to read!")
} else {
print("Not into reading.")
}
// Prints "Love to read!"
Iterating Over a Set
Iterate with a for-in
loop:
for hobby in hobbies {
print(hobby)
}
// Reading
// Hiking
// Cooking
For sorted order, use sorted()
:
for hobby in hobbies.sorted() {
print(hobby)
}
// Cooking
// Hiking
// Reading
Set Operations
Perform set operations like union, intersection, and more:
let evens: Set = [2, 4, 6, 8]
let multiplesOfThree: Set = [3, 6, 9]
let allNumbers = evens.union(multiplesOfThree).sorted()
// [2, 3, 4, 6, 8, 9]
let common = evens.intersection(multiplesOfThree).sorted()
// [6]
let uniqueEvens = evens.subtracting(multiplesOfThree).sorted()
// [2, 4, 8]
let exclusive = evens.symmetricDifference(multiplesOfThree).sorted()
// [2, 3, 4, 8, 9]
Set Membership and Equality
Check relationships between sets:
let pets: Set = ["Dog", "Cat"]
let animals: Set = ["Dog", "Cat", "Cow", "Horse"]
let wild: Set = ["Wolf", "Bear"]
print(pets.isSubset(of: animals)) // true
print(animals.isSuperset(of: pets)) // true
print(animals.isDisjoint(with: wild)) // true
Dictionaries
A dictionary stores key-value pairs without order, where keys are unique and hashable. Use dictionaries for fast lookups by key.
Note
Swift’s Dictionary
integrates with Foundation’s NSDictionary
. See Apple’s documentation for bridging details.
Dictionary Type Shorthand
Dictionaries are written as Dictionary<Key, Value>
or [Key: Value]
, where Key
is hashable. The shorthand [Key: Value]
is preferred.
Creating an Empty Dictionary
Initialize an empty dictionary with [:]
or Dictionary<Key, Value>()
:
var scores: [String: Int] = [:]
// Scores is an empty [String: Int] dictionary
Reset with [:]
:
scores["Alice"] = 95
// Scores has 1 key-value pair
scores = [:]
// Scores is empty, still [String: Int]
Creating a Dictionary with a Literal
Use a dictionary literal for initialization:
var teams = ["Red": "Team A", "Blue": "Team B"]
// Teams is [String: String] with 2 pairs
Swift infers the type if keys and values are consistent.
Accessing and Modifying Dictionaries
- Check size with
count
:
print("Teams dictionary has \(teams.count) items.")
// Prints "Teams dictionary has 2 items."
- Check if empty with
isEmpty
:
if teams.isEmpty {
print("No teams.")
} else {
print("Teams exist.")
}
// Prints "Teams exist."
- Add or update with subscript syntax:
teams["Green"] = "Team C"
// Teams now has 3 items
teams["Red"] = "Team Alpha"
// "Red" value updated to "Team Alpha"
- Update with
updateValue(_:forKey:)
:
if let oldValue = teams.updateValue("Team Beta", forKey: "Blue") {
print("Old value for Blue was \(oldValue).")
}
// Prints "Old value for Blue was Team B."
- Access values (returns optional):
if let teamName = teams["Red"] {
print("Team Red is \(teamName).")
} else {
print("Team Red not found.")
}
// Prints "Team Red is Team Alpha."
- Remove pairs by setting to
nil
or usingremoveValue(forKey:)
:
teams["Green"] = nil
// Green removed
if let removed = teams.removeValue(forKey: "Blue") {
print("Removed team: \(removed).")
}
// Prints "Removed team: Team Beta."
Iterating Over a Dictionary
Iterate with a for-in
loop:
for (color, team) in teams {
print("\(color): \(team)")
}
// Red: Team Alpha
Access keys or values separately:
for color in teams.keys {
print("Color: \(color)")
}
// Color: Red
for team in teams.values {
print("Team: \(team)")
}
// Team: Team Alpha
Convert to arrays or sort for ordered iteration:
let colors = [String](teams.keys.sorted())
// colors is ["Red"]