Start learning free

LESSON 265 OF 678 · TUPLES, SORTING & BUILT-INS

Tuples in Swift: Labels, Unpacking and Return Values

Lesson Read the full explanation

TL ; DR:

A tuple keeps a few values together, like a movie's title and year. Give its parts labels and read them with a dot, or unpack them into constants.


let movie = (title: "Frozen", year: 2013)   // a tuple with labels
print(movie.title)                          // Frozen
print(movie.1)                              // 2013, by position

let (title, year) = movie                   // unpacking
print("\(title) \(year)")                   // Frozen 2013


Full lesson:

Some values belong together. A movie has a title and a year. A point has an x and a y. A tuple keeps a few values like these in one constant.

  • (title: "Frozen", year: 2013) makes a tuple with labels. Its type is (title: String, year: Int).
  • movie.title reads a part by its label. movie.0 and movie.1 read it by its position.

let (title, year) = movie unpacks the tuple into two new constants. It works like for (name, points) in scores.

A function can return a tuple. Its return type is the tuple's type, like (title: String, year: Int). The caller unpacks it or reads result.title.

A tuple made with let can't be changed. With var, movie.year = 2014 works. Still, a tuple never gets more parts, and its types stay fixed.


Your task

Rex the dog went for a long walk. pet holds his name and his age.

First, make splitTime return its tuple: the whole hours and the minutes left.

Then unpack pet into name and age.

Last, call splitTime(135). Unpack its result into hours and mins.

The code already prints the three lines.

Expected output:

Rex
Rex is 4
Rex walked 2 h 15 min
STEP 1 OF 3
    Ctrl + Enter to check

    SWIFT · TUPLES, SORTING & BUILT-INS

    Tuples in Swift, explained

    What a tuple is

    Some values belong together: a movie has a title and a year, a point has an x and a y. A tuple keeps a few such values in one constant or variable. You write them in parentheses, separated by commas:

    let movie = (title: "Frozen", year: 2013)
    print(movie.title)
    print(movie.1)
    
    Frozen
    2013
    

    The type of movie is (title: String, year: Int). The parts can have different types, and the labels are optional. A part is read by its label (movie.title) or by its position, counting from 0 (movie.0, movie.1).

    Unpacking a tuple

    Instead of reading parts one at a time, you can unpack the whole tuple into new constants. The names go in parentheses, in the same order as the parts:

    let (title, year) = movie
    print("\(title) \(year)")
    
    Frozen 2013
    

    This is the same unpacking that for (i, item) in ... loops do later in this chapter. The number of names must match the number of parts. Unpacking movie into three names is a compile error, because the tuple has two parts. If you need only one part, write _ for the other: let (_, year) = movie.

    Returning a tuple from a function

    A function can only return one value, but that value can be a tuple. The return type is the tuple's type, and the labels are part of it. This is why the lesson's return (minutes / 60, minutes % 60) doesn't repeat the labels: the return type (hours: Int, mins: Int) already gives them. The caller either unpacks the result or reads a part by its label:

    let (hours, mins) = splitTime(135)
    print(splitTime(135).hours)
    

    With 135 minutes, hours is 2 and mins is 15; the second line prints 2.

    Constants and variables

    A tuple stored with let can't change. Assigning movie.year = 2014 fails with "cannot assign to property: 'movie' is a 'let' constant". If the tuple is stored with var, the assignment works, and it changes only that copy: a tuple is a value type, so var other = movie makes an independent copy. A tuple never gets more parts, and each part keeps its type.

    The lesson's exercise

    1. Return the tuple from splitTime. The whole hours are minutes / 60 (integer division drops the remainder), and the minutes left are minutes % 60.
    2. Unpack pet into name and age with let (name, age) = pet. The name comes first because it is the first part.
    3. Unpack the result of splitTime(135) into hours and mins the same way. A function result unpacks just like a stored tuple.
    class Solution {
        func splitTime(_ minutes: Int) -> (hours: Int, mins: Int) {
            return (minutes / 60, minutes % 60)
        }
        func mainFunction() {
            let pet = (name: "Rex", age: 4)
            print(pet.name)
            let (name, age) = pet
            print("\(name) is \(age)")
            let (hours, mins) = splitTime(135)
            print("\(name) walked \(hours) h \(mins) min")
        }
    }
    

    It prints:

    Rex
    Rex is 4
    Rex walked 2 h 15 min
    

    Common mistakes

    • Names in the wrong order. Unpacking matches by position, not by name. let (age, name) = pet compiles, but age now holds "Rex" and name holds 4, so the line prints 4 is Rex.
    • Mixing up the two operators. / gives the whole hours and % the minutes left. For 59 minutes, splitTime(59) gives (hours: 0, mins: 59).
    • Counting from 1. movie.0 is the title; there is no movie.2 on a two-part tuple.

    Key takeaways

    • A tuple groups a fixed number of values, possibly of different types, with optional labels.
    • Read parts with .label or .0, .1, or unpack them with let (a, b) = tuple.
    • A function returns several values by returning a tuple; the return type supplies the labels.
    • A let tuple can't be changed; a var tuple can, but its shape stays fixed.
    Keep going with Swift500+ step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free