タプルは、複数の値を1つの複合的な値にまとめます。 配列とは異なり、タプル内の値は同じ型である必要はなく、タプルのサイズは作成時に固定されます。
タプルを作るには、カンマで区切った値を括弧(())で囲みます。
let order = ("biscuits", 2.99, 3)
型注釈を明示的に指定することもできます。
let order: (String, Double, Int) = ("biscuits", 2.99, 3)
名前のないタプルから個々の要素を取り出すには、0から始まるインデックスの構文(.0、.1など)を使います。
let item = order.0 // "biscuits"
let quantity = order.2 // 3
タプルを定義するときに、個々の要素に名前を付けられます。
let order = (item: "biscuits", price: 2.99, quantity: 3)
要素に名前を付けるとコードが読みやすくなり、ラベルを使ったドット記法で要素にアクセスできるようになります。
let item = order.item // "biscuits"
let quantity = order.quantity // 3
型注釈の中に要素名を含めることもできます。
let order: (item: String, price: Double, quantity: Int) = (item: "biscuits", price: 2.99, quantity: 3)
タプルが変数(var)として宣言されていれば、その要素を更新できます。
var order = ("biscuits", 2.99, 3)
order.0 = "cookies"
order.1 = 1.99
order.2 = 5
print(order)
// Prints ("cookies", 1.99, 5)
Swiftの関数は1つの値しか返せませんが、タプルを返せば、関数から複数の値をまとめて返すことができます。
func divide(_ dividend: Int, by divisor: Int) -> (quotient: Int, remainder: Int) {
let quotient = dividend / divisor
let remainder = dividend % divisor
return (quotient, remainder)
}
let result = divide(14, by: 4)
print("Quotient: \(result.quotient), Remainder: \(result.remainder)")
// Prints "Quotient: 3, Remainder: 2"
タプルの値を、個別の定数や変数に分解(アンパック)できます。
let order = ("biscuits", 2.99, 3)
let (item, price, quantity) = order
print(item) // Prints "biscuits"
タプルの分解は、for-inループの中でもそのまま使えます。
let orders = [("biscuits", 2.99, 3), ("cookies", 1.99, 5)]
for (item, price, quantity) in orders {
print("Item: \(item), Price: \(price), Quantity: \(quantity)")
}
サンタクロースの物流部門で働くエルフは、上司からシステムのソフトウェアをアップグレードするための2つの仕事を任されました。
システムは、データベースからおもちゃの名前を取得できる必要があります。
データベースは、(name: String, quantity: Int)型のタプルでできています。
タプル(name: String, quantity: Int)を受け取る関数getName(_:)を実装しましょう。
let toy = (name: "Doll", quantity: 10)
getName(toy)
// Returns "Doll"
おもちゃの市場は移り変わりが早く、人気の商品もめまぐるしく変わります。 そのため、新しいおもちゃを作成する関数が必要です。
おもちゃの名前を持つ引数nameと、おもちゃの数量を持つ引数amountを受け取る関数createToy(name:amount:)を実装しましょう。
createToy(name: "Doll", amount: 10)
// Returns (name: "Doll", amount: 10)
サンタの工房のエルフたちは絶えずおもちゃを作り続けているので、サンタはおもちゃごとの数量を把握しておく必要があります。 そのために、システムはデータベース内のおもちゃの数量を更新できる必要があります。
次の引数を受け取る関数updateQuantity(_:toy:Amount:)を実装しましょう。
toysは、タプル(name: String, quantity: Int)の配列を持ちます。toyは、更新するおもちゃの名前を持ちます。amountは、おもちゃの新しい数量を持ちます。おもちゃはすでにデータベースにあると想定してよく、その確認は必要ありません。
let toys = [(name: "Doll", quantity: 10), (name: "Car", quantity: 5), (name: "Train", quantity: 3)]
updateQuantity(toys, toy: "Doll", amount: 15)
// Returns [(name: "Doll", quantity: 15), (name: "Car", quantity: 5), (name: "Train", quantity: 3)]
サンタは、データベース内のおもちゃを分類できるようにしたいと考えています。 こうすると、配達が必要なときに目的のおもちゃをすぐ見つけられ、データベース内のおもちゃを並べ替えることもできます。
しかし、システムを最初に実装したとき、カテゴリーキーは忘れられていました。 そこで今度は、システムがデータベース内のおもちゃにカテゴリーキーを追加できる必要があります。
次の引数を受け取る関数addCategory(_:category:)を実装しましょう。
toysは、タプル(name: String, quantity: Int)の配列を持ちます。categoryは、おもちゃに追加するカテゴリーキーを持ちます。おもちゃはすでにデータベースにあると想定してよく、その確認は必要ありません。 また、おもちゃにカテゴリーキーがまだないことも想定してかまいません。
let toys = [(name: "Car", quantity: 5), (name: "Train", quantity: 3)]
addCategory(toys, category: "Vehicle")
// Returns [(name: "Car", quantity: 5, category: "Vehicle"), (name: "Train", quantity: 3, category: "Vehicle")]