Tuple is collection of values of different type. It is a compound type that was not there in Objective-C, but was introduced in Swift. It holds disparate set of values inside open and closed parentheses (). With in that it can hold a group of different types of values — e.g. (Int, String) or (String, String) or (String, String, String) or (Int, Int, Int, Int).
Declaration of Tuples
Following are some examples of tuples:
var idName = (1, “John”)
// Type of Tuple: (Int, String)
var name = (“Thomas”, “J”, “Edison”)
// Type of Tuple: (String, String, String)
var error = (404, “Not Found”)
// Type of Tuple: (Int, String)
var address = ((120, “Sansome St”), “San Francisco”, 94112)
// Type of Tuple: ((Int, String), String, Int)
In the above example, type of tuples are inferred by Swift. As you can see, any number of values of different types can be grouped together. In the last example, the tuples are nested — one tuple is inside another - the tuple (Int, String) that represents the complete street is inside another larger tuple that represents the address.
Getting Elements from Tuples
There are three ways of getting the individual elements from a tuple:
- Getting the element by using a number - starting from 0
- Assign it to a tuple with named elements
- Use names of the elements, if used in the declaration
Getting the element by using a number
The individual elements inside a tuple can be referenced by numbers: 0, 1, 2, …
var name = (“Thomas”, “J”, “Edison”)
print(name.0, name.1, name.2)
// Prints: Thomas J Edison
In the above example, name tuple consists of 3 String values. The value name.0 gives the first String, name.1 gives the second String, and finally name.2 returns the third element in the tuple.
Assign a tuple value to another tuple with named elements
The individual elements of a tuple can be extracted and assigned to another tuple that has named elements.
var name = (“Thomas”, “J”, “Edison”)
let (first, middle, last) = name
print(first, middle, last)
// Prints: Thomas J Edison
The variables first, middle, and last are assigned to the three elements that make up the name tuple — in order. In this case, all those individual elements inside the tuple are String values. And by using type inference, Swift makes first, middle, and last to be of String types.
What if you don’t care about the middle initial? An _ (underscore) is used for such purposes. In Swift, wherever you see _ , it would typically mean I don’t care about it (in that context)
var name = (“Thomas”, “J”, “Edison”)
let (first, _, last) = name
print(first, last)
// Prints: Thomas Edison
Use names of elements, if used in the declaration
A tuple can be declared by naming the individual element of a tuple.
var name: (first: String, middle: String, last: String) = (“Thomas”, “J”, “Edison”)
print(“\(name.last), \(name.first)”)
// Prints: Edison, Thomas
In this case, the elements of the name tuple are named as first, middle, and last. Their type is also specified as String. And, in the print function, since these individual elements can be referred to by name, they can be accessed much more clearly.
Arrays and Tuples
How are arrays and tuples different?
Arrays hold multiple values of the same type, whereas tuples hold single values of multiple types. So, in case of an array, you can have set of String values or Int values, or of some custom type - but it’s only one type. In a tuple, the individual elements will be of any type. In an array, elements can be added or removed, they can be iterated over. In a tuple, individual elements can not be iterated over or more elements added or removed.
var names = [“Thomas”, “Steve”, “Bill”]
// Type: [String]
for name in names {
print(name)
}
var greats = (“Thomas”, “Steve”, “Bill”)
// Type: (String, String, String)
print(greats.0)
print(greats.1)
print(greats.2)
Structs and Tuples
Structs in Swift are the closest things Tuples. Tuples can be thought of as lite Structs. In addition to individual elements (properties), a struct in Swift can have methods, initializers, etc. Tuples can only have variables/constants without all the additional power that a struct has.
Usage is very similar at simpler implementations of struct:
// Declaration of struct and tuple
struct NameStruct {
var first, middle, last: String
}
var nameTuple: (first: String, middle: String, last: String)
// Assignment of values to elements
var nameStruct = NameStruct(first: “Thomas”, middle: “J”, last: “Edison”)
nameTuple = (first: “Thomas”, middle: “J”, last: “Edison”)
// Retrieval of values from elements
print(nameStruct.first, nameStruct.middle, nameStruct.last)
print(nameTuple.first, nameTuple.middle, nameTuple.last)
// Prints in both cases: Thomas J Edison
As you can see some striking similarities between structs and tuples — at simple usage of structs.
Use cases for Tuples
One of the best use case for tuples is returning multiple values from a method or function. In Objective-C and older versions of several other languages, you could only return one value from a method/function. If you wanted to return more values, you would have passed some parameters by reference and those parameters would be available from the calling code.
Any place you want a compound value (that contains individual values of different types), then you should use tuples. However, for modeling complex objects (objects with several properties and associated functionality/methods) - you should use types like struct or class.