딕셔너리는 Swift의 주요 컬렉션 타입 중 하나예요. 딕셔너리는 고유한 키와 그에 대응하는 값 사이의 순서 없는 연관을 저장해요. 딕셔너리에 있는 모든 키는 같은 타입이어야 하고, 모든 값도 같은 타입을 공유해야 해요.
딕셔너리 리터럴은 대괄호로 감싼, 쉼표로 구분된 key: value 쌍으로 작성해요:
var addresses: Dictionary<String, String> = [
"The Munsters": "1313 Mockingbird Lane",
"The Simpsons": "742 Evergreen Terrace",
"Buffy Summers": "1630 Revello Drive"
]
var sequences: [String: [Int]] = [
"Euler's totient": [1, 1, 2, 2, 4, 2, 6, 4],
"Lazy caterer": [1, 2, 4, 7, 11, 16, 22, 29, 37],
"Carmichael": [561, 1105, 1729, 2465, 2821, 6601, 8911, 10585, 15841]
]
let constants = [
"pi": 3.14159,
"e": 2.71828,
"phi": 1.618033,
"avogadro": 6.02214076e23
]
딕셔너리 타입은 두 가지 방식으로 명시적으로 작성할 수 있어요: Dictionary<Key, Value> 또는 축약 문법인 [Key: Value]예요.
빈 딕셔너리를 만들려면 키와 값 타입을 명시적으로 지정해요:
var emptyDict1: [Int: Int] = [:]
var emptyDict2 = [Character: String]()
var emptyDict3 = Dictionary<Int, Double>()
서브스크립트 표기법을 사용해 값에 접근할 수 있어요. 딕셔너리 이름 뒤의 대괄호 안에 키를 넣어요.
키가 딕셔너리에 없을 수도 있기 때문에, 서브스크립트 접근은 옵셔널(Value?)을 반환해요.
키가 있으면 Swift는 래핑된 값을 반환하고, 없으면 nil을 반환해요:
let munster: String? = addresses["The Munsters"]
// Returns Optional("1313 Mockingbird Lane")
let carmichael = sequences["Carmichael"]
// Returns Optional([561, 1105, 1729, 2465, 2821, 6601, 8911, 10585, 15841])
let planck = constants["planck"]
// Returns nil
옵셔널을 다루지 않으려면 default 매개변수를 사용해 기본값을 제공할 수 있어요:
let e: Double = constants["e", default: 0]
// Returns 2.71828
let hoagie: [Int] = sequences["Hoagie", default: []]
// Returns []
let betty = addresses["Betty Cooper", default: "Address unknown"]
// Returns "Address unknown"
var로 선언한 변경 가능한 딕셔너리에서는 서브스크립트 대입을 사용해 키-값 쌍을 추가하거나 갱신할 수 있어요:
sequences["Euler's totient"]?.append(contentsOf: [6, 4])
// sequences["Euler's totient"] is now [1, 1, 2, 2, 4, 2, 6, 4, 6, 4]
addresses["Betty Cooper"] = "111 Queens Ave."
addresses["Betty Cooper", default: "Address unknown"]
// Returns "111 Queens Ave."
constants["Gelfond's"] = 23.140692
// Compiler error: Cannot assign through subscript: 'constants' is a 'let' constant
for-in 루프를 사용해 딕셔너리의 각 키-값 쌍을 순회할 수 있어요.
각 항목은 (key, value) 튜플로 제공돼요:
for (name, address) in addresses {
print("\(name) lives at \(address)")
}
딕셔너리는 순서가 없기 때문에, 정렬하면 키-값 쌍의 배열이 만들어져요.
sorted(by:) 메서드에 클로저를 전달할 수 있는데, 이 클로저는 두 (key, value) 튜플을 비교하고 첫 번째 튜플이 두 번째보다 먼저 와야 하면 true를 반환해요:
func sortByNameLengthThenValue(_ lhs: (key: String, value: Double), _ rhs: (key: String, value: Double)) -> Bool {
let left = lhs.value + Double(lhs.key.count)
let right = rhs.value + Double(rhs.key.count)
return left < right
}
let sortedConstants = constants.sorted(by: sortByNameLengthThenValue)
이 연습 문제에서는 동네 오락실에서 가장 인기 있는 게임의 최고 점수를 기록하는 방법을 구현해요.
구현해야 할 함수는 7개이고, 모두 최고 점수 데이터를 담은 딕셔너리를 반환하고 조작하는 것과 관련이 있어요.
매개변수를 받지 않고, 키의 타입으로 String을, 값의 타입으로 Int를 사용하는 새로운 최고 점수 딕셔너리를 반환하는 newScoreBoard() 함수를 만들어요.
최고 점수 딕셔너리에 플레이어를 추가하려면, 3개의 매개변수를 받는 addPlayer(_:_:_:) 함수를 정의해요:
var highScores = newScoreBoard()
addPlayer(&highScores, "Dave Thomas")
// Returns ["Dave Thomas": 0]
addPlayer(&highScores, "José Valim", 486_373)
// Returns ["Dave Thomas": 0, "José Valim": 486_373]
최고 점수 딕셔너리에서 플레이어를 제거하려면, 2개의 매개변수를 받는 removePlayer(_:_:)를 정의해요:
이 함수는 플레이어가 딕셔너리에 있으면 제거하고, 없으면 아무것도 하지 않아요.
var highScores = ["Dave Thomas": 0, "José Valim": 486_373]
removePlayer(&highScores, "Dave Thomas")
// Returns ["José Valim": 486_373]
removePlayer(&highScores, "Rose Fanaras")
// Returns ["José Valim": 486_373]
플레이어의 점수를 초기화하려면, 2개의 매개변수를 받는 resetPlayer(_:_:)를 정의해요:
이 함수는 플레이어의 점수를 0으로 설정해요. 플레이어가 딕셔너리에 없으면 아무 일도 일어나지 않아요.
var highScores = ["Dave Thomas": 486_373, "José Valim": 10]
resetScore(&highScores, "Dave Thomas")
// Returns ["Dave Thomas": 0, "José Valim": 10]
이전 점수에 더해서 플레이어의 점수를 업데이트하려면, 3개의 매개변수를 받는 updateScore를 정의해요:
var highScores = ["Dave Thomas": 0, "José Valim": 486_373]
addPlayer(&highScores, "Freyja Ćirić", 12_771_008)
updateScore(&highScores, "Freyja Ćirić", 73)
// Returns ["Dave Thomas": 0, "José Valim": 486_373, "Freyja Ćirić": 12_771_081]
1개의 매개변수를 받는 orderByPlayers 함수를 정의해요:
이 함수는 플레이어와 그들의 최고 점수를 플레이어 이름의 오름차순으로 정렬한 (String, Int) 튜플의 배열을 반환해요.
var highScores = ["Dave Thomas": 0, "José Valim": 486_373, "Freyja Ćirić": 12_771_091]
orderByPlayers(highScores)
// Returns [("Dave Thomas", 0), ("Freyja Ćirić", 12_771_091), ("José Valim", 486_373)]
플레이어를 점수의 내림차순으로 정렬한 목록을 가져오려면, 1개의 매개변수를 받는 orderByScores를 정의해요:
이 함수는 플레이어와 그들의 최고 점수를 플레이어 점수의 내림차순으로 정렬한 (String, Int) 튜플의 배열을 반환해요.
var highScores = ["Dave Thomas": 0, "José Valim": 486_373, "Freyja Ćirić": 12_771_091]
orderByScores(highScores)
// Returns [("Freyja Ćirić", 12_771_091), ("José Valim", 486_373), ("Dave Thomas", 0)]
Exercism에 가입하고 Swift 트랙을 개념 35개연습 문제 116개, 그리고 실제 사람의 멘토링과 함께 배우고 익혀 보세요. 모두 무료예요.