Swift Tuples
A tuple groups multiple values into a single compound value. Unlike arrays, tuples can hold values of different types and have a fixed number of elements. Think of a tuple like a labeled lunch box — it holds a sandwich, a drink, and a fruit all in one container, each in its own compartment.
Creating a Tuple
let point = (3, 7)
let person = ("Alice", 30)
let color = (red: 255, green: 128, blue: 0)The first two tuples use positional access. The third uses named elements, which makes code easier to read.
Accessing Tuple Values
By Position (Index)
let coordinates = (40.7128, -74.0060)
print(coordinates.0) // Output: 40.7128 (latitude)
print(coordinates.1) // Output: -74.006 (longitude)By Name
let product = (name: "Laptop", price: 999.99, inStock: true)
print(product.name) // Output: Laptop
print(product.price) // Output: 999.99
print(product.inStock) // Output: trueDiagram: Tuple Structure
let product = (name: "Laptop", price: 999.99, inStock: true) +----------+----------+-----------+ | "Laptop" | 999.99 | true | +----------+----------+-----------+ .name .price .inStock String Double Bool Three different types in one value.
Tuple Decomposition
Decomposition unpacks a tuple into individual named constants in one line.
let status = (code: 200, message: "OK")
let (code, message) = status
print(code) // Output: 200
print(message) // Output: OKIgnoring Elements With _
let response = (200, "OK", 1.23)
let (statusCode, _, responseTime) = response
print(statusCode) // Output: 200
print(responseTime) // Output: 1.23
// The middle value "OK" is ignoredTuples as Function Return Values
Functions return only one value. A tuple solves this by bundling multiple values into that one return.
func getMinMax(from numbers: [Int]) -> (min: Int, max: Int) {
var min = numbers[0]
var max = numbers[0]
for n in numbers {
if n < min { min = n }
if n > max { max = n }
}
return (min, max)
}
let result = getMinMax(from: [4, 1, 9, 3, 7])
print("Min: \(result.min)") // Output: Min: 1
print("Max: \(result.max)") // Output: Max: 9Tuples in Switch Statements
Matching on tuples lets you test multiple conditions at once.
let coordinate = (0, 5)
switch coordinate {
case (0, 0):
print("Origin")
case (let x, 0):
print("On x-axis at \(x)")
case (0, let y):
print("On y-axis at \(y)")
case (let x, let y) where x == y:
print("On diagonal at \(x)")
default:
print("Somewhere else: \(coordinate)")
}
// Output: On y-axis at 5Tuples vs Structs
| Feature | Tuple | Struct |
|---|---|---|
| Named members | Optional | Always |
| Methods | No | Yes |
| Reusable as a type | No | Yes |
| Best for | Temporary, lightweight grouping | Persistent, named data model |
Use tuples for quick, short-lived groupings — especially function return values. Use structs when the data model needs to travel through your codebase or grow over time.
Named Tuple as a Type Alias
Give a tuple shape a reusable name using typealias.
typealias HTTPResponse = (statusCode: Int, body: String)
func fetchHome() -> HTTPResponse {
return (200, "<html>Hello</html>")
}
let response: HTTPResponse = fetchHome()
print(response.statusCode) // Output: 200
print(response.body) // Output: <html>Hello</html>Comparing Tuples
Swift compares tuples element by element from left to right, as long as each element type is Comparable. Tuples up to 6 elements support == and <.
print((1, "apple") < (2, "banana")) // true (1 < 2)
print((3, "kiwi") < (3, "mango")) // true (3==3, "kiwi" < "mango")
print((5, "zebra") == (5, "zebra")) // truePractical Example: HTTP Status Decoder
func decode(status: Int) -> (category: String, message: String) {
switch status {
case 200...299:
return ("Success", "Request completed.")
case 300...399:
return ("Redirect", "Resource moved.")
case 400...499:
return ("Client Error", "Bad request.")
case 500...599:
return ("Server Error", "Server failed.")
default:
return ("Unknown", "Unrecognised status.")
}
}
let info = decode(status: 404)
print("\(info.category): \(info.message)")
// Output: Client Error: Bad request.Summary
Tuples group multiple values of different types into a single lightweight container. Access elements by position (.0, .1) or by name. Decompose them into individual constants for clean code. They shine as function return types when you need to send back two or three related pieces of data without defining a full struct.
