Language
日本語
English

Caution

JavaScript is disabled in your browser.
This site uses JavaScript for features such as search.
For the best experience, please enable JavaScript before browsing this site.

  1. Home
  2. SwiftBeginner - About Tuples

About Tuples - Images: Japanese

Hey there, everyone!

Next up, let's take a look at 'Tuples'. Like arrays and dictionaries, a tuple is a way to group multiple values together.

So you might be wondering, "What's the difference from arrays and dictionaries?" Well, arrays and dictionaries in Swift are very strict about data types — basically, only values of the same type can go in. That makes things a bit of a hassle when you want to temporarily store multiple values of different types.

If you want to store values of different types in an array or dictionary, you'd have to use something like Any or AnyObject — but then every time you try to use those values, you'd have to cast them to the right type before doing any operations. Not exactly convenient.

With a Tuple, however, each value keeps its original type. That means you can work with the values directly without having to cast them every time — which makes tuples really powerful in certain situations.

Alright, let's get into it. To define a tuple, you write a pair of parentheses '()' and put your values inside. Like this:

let t = ("Hatsune Miku", 100, 0.5) // Defines a tuple.

print(t) // Outputs '("Hatsune Miku", 100, 0.5)'.

You can also put arrays or dictionaries inside a tuple. In that case, adding some indentation like below can make it easier to read. Feel free to format it however you like.

let t = ( // Arrays and dictionaries can go in too. Indenting like this can help readability.
    [0, 1, 2],
    ["Hatsune Miku": "080-xxxx-yyyy"]
)

print(t) // Outputs '([0, 1, 2], ["Hatsune Miku": "080-xxxx-yyyy"])'.

As you can see from these examples, a tuple can hold values of any data type — and that's exactly what makes tuples so handy.

You can also write a tuple inline without assigning it to a variable or constant. Here's an example where a tuple is written directly inside the parentheses of print():

print(("Hatsune Miku", 100, 0.5)) // Outputs '("Hatsune Miku", 100, 0.5)'.

As you can see, just defining a tuple is super easy.

Next, let's look at how to access the individual values inside a tuple. Take a look at this sample:

let t = ("Hatsune Miku", 100, 0.5) // Defines a tuple.

The tuple stored in the constant t contains "Hatsune Miku", 100, and 0.5. To access each value, you write 'tupleName.index' — like t.0, t.1, and so on. It's similar to how arrays work. Here's an example:

let t = ("Hatsune Miku", 100, 0.5) // Defines a tuple.

print(t.0) // Outputs '"Hatsune Miku"'.

One thing to watch out for: just like with arrays, indexing starts at 0, not 1. Don't get that mixed up!

By the way, here's how you access values when an array is nested inside a tuple:

let t = ("Hatsune Miku", [0, 1, 2])

print(t.1[0]) // Outputs '0'.

The pattern is tupleName.index[arrayIndex]. It can look a bit number-heavy, but just push through — you'll get used to it!

Now, you can also attach 'labels' to the elements in a tuple. Let's check out how that works. Here's how you define a labeled tuple:

let t = (name: "Hatsune Miku", tellNum: "080-xxxx-yyyy")

print(t) // Outputs '("Hatsune Miku", "080-xxxx-yyyy")'.

As shown above with (name: "Hatsune Miku", tellNum: "080-xxxx-yyyy"), you just write 'label: value' for each element.

To access a value by label, you do the following. Here we're printing the name element of tuple t:

let t = (name: "Hatsune Miku", tellNum: "080-xxxx-yyyy")

print(t.name) // Outputs '"Hatsune Miku"'.

As shown above, you can access a value with 'tupleName.labelName'. Earlier we used tupleName.index which felt array-like, but now we're accessing it with a label name — which feels more like a dictionary.

One thing to note: even when a tuple has labels, you can still access values by index. Like this:

let t = (name: "Hatsune Miku", tellNum: "080-xxxx-yyyy")

// Both of the following work fine.
print(t.0) // Outputs '"Hatsune Miku"'.
print(t.name) // Outputs '"Hatsune Miku"'.

So think of labels as optional extras — having a label doesn't mean you lose the ability to access by index. Keep that in mind!

Here's another thing to watch out for. When you're defining a tuple with () and only put a single element inside, it won't be treated as a tuple. Take a look at this sample:

let t = ("Hatsune Miku")

If you assume the constant t above is a tuple and write the following, you'll get an error:

let t = ("Hatsune Miku")

print(t.0) // Error.

In this case, the () in ("Hatsune Miku") is treated as grouping parentheses — the same kind used in math to control order of operations, like (1 + 3) × 3. Not tuple parentheses.

So in this case, t is not a tuple, and if you just want to print "Hatsune Miku", you'd do it like this:

let t = ("Hatsune Miku")

print(t) // Outputs '"Hatsune Miku"'.

Just referencing t directly works fine.

And since it's not a tuple, trying to add a label will also cause an error:

let t = (name: "Hatsune Miku")

print(t.name) // Error.

So remember: a tuple needs at least two elements. Don't forget that!

Now let's look at a handy advanced technique using tuples.

It's actually possible to use a tuple on the left side of an assignment to distribute values directly into separate variables or constants. That might sound a little confusing in words, so let's just look at a sample:

let (n, s) = (1, "Hatsune Miku")

print(n) // Outputs '1'.
print(s) // Outputs '"Hatsune Miku"'.

Focus on the part (n, s) = (1, "Hatsune Miku"). Since we used let, we're defining constants — with (n, s) on the left and (1, "Hatsune Miku") on the right. This assigns 1 to n and "Hatsune Miku" to s.

In other words, it produces the same result as this:

// The sample above produces the same result as this.
let n = 1, s = "Hatsune Miku"

print(n) // Outputs '1'.
print(s) // Outputs '"Hatsune Miku"'.

So what's the difference between writing let (n, s) = (1, "Hatsune Miku") versus let n = 1, s = "Hatsune Miku"? Let's revisit a sample from near the end of the previous article. This one:

func test(n: Int, s: String) -> (Int, String) {
    return (n, s)
}

let tpl = test(n: 10, s: "Hatsune Miku")

print(tpl) // Outputs '(10, "Hatsune Miku")'.

The function test above returns an Int and a String together as a tuple, as indicated by -> (Int, String). The constant tpl catches the whole thing at once.

But sometimes you might want to catch each returned value from a function into its own separate constant or variable. That's where our new notation comes in handy. Here's how it looks:

func test(n: Int, s: String) -> (Int, String){
    return (n, s)
}

let (num, str) = test(n: 10, s: "Hatsune Miku") // Catch each return value in its own constant.

print(num) // Outputs '10'.
print(str) // Outputs '"Hatsune Miku"'.

This notation is really powerful, so make sure you remember it.

When assigning from a tuple into variables or constants, if you want to skip over some of the values, use _. Take a look at this sample:

let (_, n, _, s) = (1, 2, 3, "Hatsune Miku")

print(n) // Outputs '2'.
print(s) // Outputs '"Hatsune Miku"'.

In this sample, the 0th and 2nd elements of the tuple (1, 2, 3, "Hatsune Miku") are skipped, and only the remaining values are assigned.

By placing a _ wherever you want to ignore an element, you can skip those positions during assignment.

This is quite useful, so give it a try!

And that covers tuples! In the next article, we'll look at function 'overloading'. See you there!

This article was written by Sakurama.

Author's beloved small mammal

桜舞 春人 Sakurama Haruto

A Tokyo-based programmer who has been creating various content since the ISDN era, with a bit of concern about his hair. A true long sleeper who generally feels unwell without at least 10 hours of sleep. His dream is to live a life where he can sleep as much as he wants. Loves games, sports, and music. Please share some hair with him.

If you find any errors or copyright issues, please .