딕셔너리는 요소들의 순서 없이 키와 값의 쌍으로 구성되는 컬렉션 타입이다. 딕셔너리에 저장되는 값을 항상 키와 쌍을 이루게 되는데, 딕셔너리안에는 키가 하나이거나 여러개일 수 있다.
배열과 마찬가지로 값의 모음이지만 정수 위치로 항목을 저장하는 대신 원하는 것을 사용하여 접근할 수 있다.
단, 하나의 딕셔너리안의 키는 같은 이름을 중복해서 사용할 수 없다. 즉, 딕셔너리에 키는 값을 대변하는 유일한 식별자가 되는 것이다.
딕셔너리 데이터를 저장하는 가장 일반적인 방법은 문자열을 사용하는 것이다. 예를 들어 이름을 사용하여 사람의 키를 저장하는 사전을 만들 수 있다.
let heights = [ "하울": 1.78, "서근": 1.76 ]
배열과 마찬가지로 딕셔너리는 대괄호
를 사용하고 , 콜론(:)
을 사용해서 값과 식별자를 구분한다. 이 식별자를 key
라고 하며, 딕셔너리에서 데이터를 다시 읽을 수 있다!!!!
heights["서근"]
딕셔너리와 배열은 서로 다른 방법으로 저장한다.
딕셔너리를 사용하면 추가하려는 항목을 식별하는 "키"를 선택할 수 있지만 , 배열은 각 항목을 순차적으로 추가한다.
예를들어 Array
인덱스[7] 이 사용자의 국가를 의미한다는 것을 기억하려고 하기보다, user["country"]
라고 쓰는 것이 훨씬 편하다.
세트와 마찬가지로 딕셔너리는 특정 순서로 항목을 저장하지 않으므로 빠른 검색 을 위해 항목을 저장하는 방식을 최적화한다.
따라서 user["country"]
라고 호출을 하면 내부에 있는 1000개의 항목이 있는 딕셔너리가 있어도 해당 키(또는 nill
)에 있는 항목을 즉시 반환한다.
var roles = ["captain": "Mal", "engineer": "Kaylee"]
let scores = ["Sophie": 100]
존재하지 않는 키(nil)을 사용하여 딕셔너리에서 값을 읽으려고 하면 nil을 돌려준다. 누락 된 키를 요청하는 경우 사용할 기본값을 딕셔저너리에 제공할 수 있다.
let favoriteIceCream = [ "서근": "초콜릿", "포뇨": "바닐라" ]
서근이 가장 좋아하는 아이스크림을 다음과 같이 읽을 수 있다.
favoriteIceCream["서근"]
하지만 하울에게 가장 좋아하는 아이스크림을 읽으려고 하면 nil이 반환된다. 이는 Swift에는 해당 키에 대한 값이 없음을 의미한다.
favoriteIceCream["하울"]
디셔너리에 "Unknown"의 기본값을 지정하여이 문제를 해결할 수 있다. 이렇게 기본값을 정해주면 '하울'에 대한 아이스크림이 없을 때 nil이 아닌 "Unknown"이 반환된다.
favoriteIceCream["하울", default: "Unknown"]
// typealias를 사용해 더 단순하게 표현 가능
typealias StringIntDictionary = [String: Int]
// 키는 String, 값은 Int 타입인 빈 딕셔너리 생성
// 모두 같은 표현
var nameAndAge1: [String: Int] = [String: Int]()
var nameAndAge2: Dictionary<String, Int> = Dictionary<String, Int>()
var nameAndAge3: StringIntDictionary = StringIntDictionary()
// 딕셔너리의 키와 값 타입을 정확히 명시해줬다면, [:] 만으로도 빈 딕셔너리 생성 가능
var nameAndAge4: [String: Int] = [:]
var nameAndAge5: [String: Int] = ["서근": 25, "미진": 19, "철수": 12]
print(nameAndAge4.isEmpty) // true
print(nameAndAge5.isEmpty) // false
print(nameAndAge5.count) // 3
print(nameAndAge5) // ["철수": 12, "미진": 19, "서근": 25]
위에서 말했듯이 , 딕셔너리는 각 값에 키로 접근할 수 있다. 딕셔너리 내부에서 키는 유일해야하고 , 값은 유일하지 않다
.
딕셔너리는 배열과 다르게 딕셔너리 내부에 없는 키로 접근해도 오류가 발생하지 않고 nil
을 반환한다.
특정 키에 해당하는 값을 제거하려면 removeValue(forkey:)
메소드를 사용한다. 키에 해당하는 값이 제거된 후 반환된다.(set과 같음)
var nameAndAge4: [String: Int] = [:]
var nameAndAge5: [String: Int] = ["서근": 25, "미진": 19, "철수": 12]
print(nameAndAge4.isEmpty) // true
print(nameAndAge5.isEmpty) // false
print(nameAndAge5.count) // 3
print(nameAndAge5) // ["철수": 12, "미진": 19, "서근": 25]
print(nameAndAge5["서근"]) // 25
print(nameAndAge5["소피아"]) // nil
nameAndAge5["소피아"] = 20
print(nameAndAge5["소피아"]) // 20
print(nameAndAge5.removeValue(forKey: "미진")) //19
print(nameAndAge5) // ["소피아": 20, "철수": 12, "서근": 25]
print(nameAndAge5.removeValue(forKey: "미진")) // nil
print(nameAndAge5["미진", default: 0]) // 미진은 nil이지만 기본값을 0으로 지정해줬기 때문에 0