Tuples Explained in Swift

Written by Reinder de Vries on July 1 2020 in App Development

Tuples Explained in Swift

You use tuples in Swift to make ordered, comma-separated lists of values. They may look small, but they’re quite powerful! In this article, we’ll discuss how you can use tuples in practical iOS development.

Let’s get started!

  1. What’s a Tuple?
  2. Decomposing Tuples
  3. Tuples in Everyday Swift Coding
  4. Further Reading

What’s a Tuple?

A tuple (pronounced “TEW-ple”) is an ordered, comma-separated list of values, wrapped in parentheses.

Here’s an example:

let flight = ("LAX", 747)
print("We're flying to \(flight.0) in a \(flight.1)")

In the above code, the tuple is ("LAX", 747). You can clearly see two values, separated by a comma, wrapped in parentheses. In everyday coding, it’s easiest to recognize a tuple by its use of commas and parentheses.

The tuple’s type is (String, Int). The type of the first value is String, and the second value’s type is Int. Again separated by a comma, and wrapped in parentheses.

In the previous example, we’ve also used syntax to get the tuple’s values. The tuple is a list, and we can get to its values by using indices 0, 1, etcetera. In the next section, we’ll look at more ways to deal with values.

Don’t confuse tuples with arrays, dictionaries or sets though! They aren’t collections, but they do group values together. A tuple’s values can have different types, and you can change their values, provided it’s declared as mutable with var. But, after initialization, you can’t add any more items to it.

A tuple’s order can’t change after it is initialized. So, the ones below don’t have identical types:

("LAX", 747) // Type is (String, Int)
(747, "LAX") // Type is (Int, String)

The order is important here. Even though both contain the same values with the same type, their types are different because the order of values is different.

You can compare tuples with each other if the their types are the same, and if the types themselves conform to the Equatable protocol. In other words, if you can compare a their values, you can compare the tuples themselves too.

Here’s an example:

let a = ("AMS", 737)
let b = ("LAX", 737)

a == b // Is "false", tuples are equatable because String and Int are

let c = ("AMS", "A330-800")
c == b // Compiler error, because types don't match

In the first part of the above code, we’re comparing tuples with each other that have the same type. The individual types conform to Equatable, so we can determine equality with ==. The second example is a bit contrived, but obvious: you can’t compare incompatible types (String, Int) and (String, String).

Tuple is pronounced “TEW-ple”, like “tuner” and “apple”. The word stems from the number 2, because a typical tuple has two values. You can use different names though, such as single for one value, and pair for two values, triple for 3 values, etcetera, but they’re most commonly referred to simply as “tuples”. In Swift, the null tuple (), which has zero values, is equal to Void.

Learn how to build iOS apps

Get started with iOS 13 and Swift 5

Sign up for my iOS development course, and learn how to build great iOS 13 apps with Swift 5 and Xcode 11.

Decomposing Tuples

You don’t have to reference a tuple’s values by their indices. You can use variable names instead! Let’s take a look at an example.

let flight = (airport: "LAX", airplane: 747, heading: 270)
print("We're flying a \(flight.airplane) towards \(flight.airport) with heading \(flight.heading) degrees.")

Interesting, right? We’re using syntax like flight.airport to get one of the values from flight. The tuple itself is defined with 3 names and 3 values, separated with colons and commas. This syntax is similar to how you access an object’s properties.

What if you get passed a tuple, and you want to assign its individual values to distinct variable names? That’s where decomposition comes in. You can essentially “decompose” the tuple into separate variables or constants.

Like this:

let (airport, _, heading) = ("LAX", 747, 270)
print(airport)

Here’s what happens in the above code:

  • The tuple is ("LAX", 747, 270). It’s not assigned as a whole to a variable or constant, but instead its values are decomposed into separate constants airport and heading.
  • We’re printing the airport constant, with its value "LAX". This value originates from the tuple, but it’s now a separate constant because of decomposition.
  • The underscore _ is a value that we’re ignoring. This is typical Swift syntax that you may have seen before, for example in for loops with for _ in 1...5 { ···.

Consider, for example, that we’re using a function that’ll return a HTTP status code to us. Such a code typically consists of a number, like 404, and some text, like Not Found. Imagine that the function is part of a framework, so we can’t change its code.

Here we go:

func getStatusCode() -> (Int, String) {
return (404, "Not Found")
}

let (code, text) = getStatusCode()
print("The request returned with status code \(code) and said: '\(text)'")

See what’s happening there? The function returns a tuple of type (Int, String). It looks like two values. How is that possible? Technically, the function returns one value – a tuple – which consists of two values, an integer and a string. (Check this for yourself, by looking at the function return type!)

We want to access the individual values, so we’re decomposing the tuple with (code, text). From there, we can use the individual constants code and text to print out the values. Awesome!

Decomposing a tuple can also be called “destructuring”, “destructing” or “deconstructing”. Whatever you call it – you’re taking it apart!

Tuples in Everyday Swift Coding

Tuples may seem insignificant, but they’re quite useful in practical iOS development. We’ve already looked at a typical use case: returning more than one value from a function. What else can you do with them?

You can see tuples as if they’re tiny classes, that you can use without defining an actual class first.

Here, check this out:

class Flight {
    var airport:String
    var airplane:Int
}

let flight = Flight(airport: "AMS", airplane: 330)
print("We're going to \(flight.airport)...")

The above code first defines a class Flight, and then initializes an instance of that class, ultimately printing out flight.airport. We can do the same thing with tuples – with a whole lot less code.

let flight = (airport: "AMS", airplane: 330)
print("We're going to \(flight.airport)...")

Neat! You can even enforce the tuple’s type by using a type alias, like this:

typealias Flight = (airport: String, airplane: Int)
let flight:Flight = ("HND", 737)
print("We're going to \(flight.airport)...")

On the first line of the above code, we’re creating an alias named Flight for the tuple type. From then on, we can use the tuple type itself and its alias interchangeably. On the second and third line, we’re annotating flight with the Flight type, and then print its value for airport.

What’s also interesting, is that you can use the the Flight type in the above code without also declaring the names of the tuple’s value. You can see this on the second line in the above code. The type is set to Flight and the tuple value is ("HND", 737) instead of (airport: "HND", airplane: 737). That’s much more concise!

And last but not least, tuples can be used to access the indices and values of array items by using the enumerated() function. Here’s how:

let drivers = ["Magnussen", "Raikkonen", "Hamilton", "Verstappen"]

for (index, name) in drivers.enumerated()
{
    print("\(name) has position \(index)")
}

In the above code, the function enumerated() on the drivers array returns a list of pairs – a tuple – with array indices and values. We’re decomposing that tuple with (index, name), so we can access the individual indices and values. Neat!

Fun Fact: Up to Swift 2.1, a function’s parameters were actually tuples, called tuple splats. After all, a function’s parameters are also written with parentheses, colons and commas. You can’t use this in Swift 5, though, because the syntax caused more harm than it did good.

Learn how to build iOS apps

Get started with iOS 13 and Swift 5

Sign up for my iOS development course, and learn how to build great iOS 13 apps with Swift 5 and Xcode 11.

Further Reading

Tuples are so simple, yet so powerful. Who would have thought that some values wrapped in parentheses could help you write code so productively?

In this article, we’ve discussed what tuples are and how you can use them in Swift. We’ve looked at decomposition, tuple types, and practical use cases for everyday iOS development.

Tuples are part of collections in Swift. We’ve got a few collection types, such as:

Want to learn more? Check out these resources:

Reinder de Vries

Reinder de Vries

Reinder de Vries is a professional iOS developer. He teaches app developers how to build their own apps at LearnAppMaking.com. Since 2009 he has developed a few dozen apps for iOS, worked for global brands and lead development at several startups. When he’s not coding, he enjoys strong espresso and traveling.

×

Build great iOS apps
Learn how in my free 7-day course

  • This field is for validation purposes and should be left unchanged.

No spam, ever. Unsubscribe anytime. Privacy Policy