Tuples
Introduction#
A tuple type is a comma-separated list of types, enclosed in parentheses.
This list of types also can have name of the elements and use those names to refer to the values of the individual elements.
An element name consists of an identifier followed immediately by a colon (:).
Common use -
We can use a tuple type as the return type of a function to enable the function to return a single tuple containing multiple values
Remarks#
Tuples are considered value types. More info on tuples could be found in the documentation: developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/TheBasics.html
What are Tuples?
Tuples group multiple values into a single compound value. The values within a tuple can be of any type and do not have to be of the same type as each other.
Tuples are created by grouping any amount of values:
let tuple = ("one", 2, "three")
// Values are read using index numbers starting at zero
print(tuple.0) // one
print(tuple.1) // 2
print(tuple.2) // three
Also individual values can be named when the tuple is defined:
let namedTuple = (first: 1, middle: "dos", last: 3)
// Values can be read with the named property
print(namedTuple.first) // 1
print(namedTuple.middle) // dos
// And still with the index number
print(namedTuple.2) // 3
They can also be named when being used as a variable and even have the ability to have optional values inside:
var numbers: (optionalFirst: Int?, middle: String, last: Int)?
//Later On
numbers = (nil, "dos", 3)
print(numbers.optionalFirst)// nil
print(numbers.middle)//"dos"
print(numbers.last)//3
Decomposing into individual variables
Tuples can be decomposed into individual variables with the following syntax:
let myTuple = (name: "Some Name", age: 26)
let (first, second) = myTuple
print(first) // "Some Name"
print(second) // 26
This syntax can be used regardless of if the tuple has unnamed properties:
let unnamedTuple = ("uno", "dos")
let (one, two) = unnamedTuple
print(one) // "uno"
print(two) // "dos"
Specific properties can be ignored by using underscore (_
):
let longTuple = ("ichi", "ni", "san")
let (_, _, third) = longTuple
print(third) // "san"
Tuples as the Return Value of Functions
Functions can return tuples:
func tupleReturner() -> (Int, String) {
return (3, "Hello")
}
let myTuple = tupleReturner()
print(myTuple.0) // 3
print(myTuple.1) // "Hello"
If you assign parameter names, they can be used from the return value:
func tupleReturner() -> (anInteger: Int, aString: String) {
return (3, "Hello")
}
let myTuple = tupleReturner()
print(myTuple.anInteger) // 3
print(myTuple.aString) // "Hello"
Using a typealias to name your tuple type
Occasionally you may want to use the same tuple type in multiple places throughout your code. This can quickly get messy, especially if your tuple is complex:
// Define a circle tuple by its center point and radius
let unitCircle: (center: (x: CGFloat, y: CGFloat), radius: CGFloat) = ((0.0, 0.0), 1.0)
func doubleRadius(ofCircle circle: (center: (x: CGFloat, y: CGFloat), radius: CGFloat)) -> (center: (x: CGFloat, y: CGFloat), radius: CGFloat) {
return (circle.center, circle.radius * 2.0)
}
If you use a certain tuple type in more than one place, you can use the typealias
keyword to name your tuple type.
// Define a circle tuple by its center point and radius
typealias Circle = (center: (x: CGFloat, y: CGFloat), radius: CGFloat)
let unitCircle: Circle = ((0.0, 0.0), 1)
func doubleRadius(ofCircle circle: Circle) -> Circle {
// Aliased tuples also have access to value labels in the original tuple type.
return (circle.center, circle.radius * 2.0)
}
If you find yourself doing this too often, however, you should consider using a struct
instead.
Swapping values
Tuples are useful to swap values between 2 (or more) variables without using temporary variables.
Example with 2 variables
Given 2 variables
var a = "Marty McFly"
var b = "Emmett Brown"
we can easily swap the values
(a, b) = (b, a)
Result:
print(a) // "Emmett Brown"
print(b) // "Marty McFly"
Example with 4 variables
var a = 0
var b = 1
var c = 2
var d = 3
(a, b, c, d) = (d, c, b, a)
print(a, b, c, d) // 3, 2, 1, 0
Tuples as Case in Switch
Use tuples in a switch
let switchTuple = (firstCase: true, secondCase: false)
switch switchTuple {
case (true, false):
// do something
case (true, true):
// do something
case (false, true):
// do something
case (false, false):
// do something
}
Or in combination with an Enum For example with Size Classes:
let switchTuple = (UIUserInterfaceSizeClass.Compact, UIUserInterfaceSizeClass.Regular)
switch switchTuple {
case (.Regular, .Compact):
//statement
case (.Regular, .Regular):
//statement
case (.Compact, .Regular):
//statement
case (.Compact, .Compact):
//statement
}