트랙
/
Swift
Swift
/
연습 문제
/
산타의 Swifty 조수
산타의 Swifty 조수

산타의 Swifty 조수

학습 연습 문제

소개

튜플은 여러 값을 하나의 복합 값으로 묶어요. 배열과 달리 튜플에 담기는 값들은 같은 타입일 필요가 없고, 튜플의 크기는 한 번 만들면 고정돼요.

쉼표로 구분한 값들을 괄호로 감싸면 튜플을 만들 수 있어요:

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)")
}

지침

여러분은 산타클로스의 물류 부서에서 일하는 엘프예요. 상사에게서 시스템 소프트웨어를 업그레이드하라는 두 가지 작업을 받았어요.

1. 장난감 이름 가져오기

시스템은 데이터베이스에서 장난감의 이름을 가져올 수 있어야 해요. 데이터베이스는 (name: String, quantity: Int) 타입의 튜플로 이루어져 있어요.

(name: String, quantity: Int) 타입의 튜플을 담은 인자를 받는 getName(_:) 함수를 구현해요.

let toy = (name: "Doll", quantity: 10)
getName(toy)
// Returns "Doll"

2. 데이터베이스에 새 장난감 추가하기

장난감 시장은 변화가 빠르고, 인기 있는 것이 아주 빠르게 바뀌어요. 따라서 새 장난감을 만드는 함수가 필요해요.

장난감의 이름을 담는 인자 name과 장난감의 수량을 담는 인자 amount를 받는 createToy(name:amount:) 함수를 구현해요.

createToy(name: "Doll", amount: 10)
// Returns (name: "Doll", amount: 10)

3. 장난감 수량 업데이트하기

산타의 작업장에 있는 엘프들은 끊임없이 장난감을 만들어요. 그래서 산타는 각 장난감의 수량을 계속 파악해야 해요. 이를 위해 시스템은 데이터베이스에 있는 장난감의 수량을 업데이트할 수 있어야 해요.

다음 인자들을 받는 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)]

4. 장난감에 카테고리 키 추가하기

산타는 데이터베이스에 있는 장난감을 분류하고 싶어 해요. 배달할 때 장난감을 쉽게 찾고, 데이터베이스의 장난감을 정렬할 수 있게 하기 위해서예요.

그런데 시스템을 처음 구현할 때 카테고리 키를 빠뜨렸어요. 이제 시스템은 데이터베이스의 장난감에 카테고리 키를 추가할 수 있어야 해요.

다음 인자들을 받는 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")]
GitHub에서 편집 링크가 새 창이나 탭에서 열려요
Swift Exercism

산타의 Swifty 조수 문제를 시작해 볼 준비가 됐나요?

Exercism에 가입하고 Swift 트랙을 개념 35개연습 문제 116개, 그리고 실제 사람의 멘토링과 함께 배우고 익혀 보세요. 모두 무료예요.