튜플은 여러 값을 하나의 복합 값으로 묶어요. 배열과 달리 튜플에 담기는 값들은 같은 타입일 필요가 없고, 튜플의 크기는 한 번 만들면 고정돼요.
쉼표로 구분한 값들을 괄호로 감싸면 튜플을 만들 수 있어요:
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 함수는 값을 하나만 반환할 수 있지만, 튜플을 반환하면 여러 값을 묶어서 함수에서 여러 값을 반환할 수 있어요:
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)")
}
여러분은 산타클로스의 물류 부서에서 일하는 엘프예요. 상사에게서 시스템 소프트웨어를 업그레이드하라는 두 가지 작업을 받았어요.
시스템은 데이터베이스에서 장난감의 이름을 가져올 수 있어야 해요.
데이터베이스는 (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:) 함수를 구현해요:
(name: String, quantity: Int) 타입의 튜플 배열을 담는 toys.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:) 함수를 구현해요:
(name: String, quantity: Int) 타입의 튜플 배열을 담는 toys.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")]
Exercism에 가입하고 Swift 트랙을 개념 35개연습 문제 116개, 그리고 실제 사람의 멘토링과 함께 배우고 익혀 보세요. 모두 무료예요.