딕셔너리 Dictionary
딕셔너리는 요소들의 순서 없이 키와 값의 쌍으로 구성되는 컬렉션 타입입니다. 딕셔너리에 저장되는 값은 항상 키와 쌍을 이루게 되는데, 딕셔너리안에는 키가 하나이거나 여러 개일 수 있습니다. 배열과 마찬가지로 값의 모음이지만 정수 위치로 항목을 저장하는 대신 원하는 것을 사용하여 액세스 할 수 있습니다.
단, 하나의 딕셔너리안의 키는 같은 이름을 중복해서 사용할 수 없습니다. 즉, 딕셔너리에 키는 값을 대변하는 유일한 식별자가 되는 것입니다.
딕셔너리는 Dictionary
라는 키워드와 키의 타입과 값의 타입 이름의 조합으로 써줍니다.
딕셔너리 데이터를 저장하는 가장 일반적인 방법은 문자열을 사용하는 것입니다. 예를 들어 이름을 사용하여 사람의 키를 저장하는 사전을 만들 수 있습니다. let
키워드를 사용하여 상수로 선언하면 변경 불가능한 딕셔너리, var
키워드를 사용하여 변수로 선언해 주성할 수 있습니다. 마찬가지로 isEmpty
프로퍼티를 통해 비어있는 딕셔너리 인지 확인할 수 있겠죠. 그리고 count
프로퍼티로 딕셔너리의 요소 개수를 확인할 수 있습니다.
let heights = [ "하울": 1.78, "서근": 1.76 ]
배열과 마찬가지로 사전은 대괄호로 시작하고 대괄호로 끝나며 각 항목은 쉼표로 구분됩니다. 그러나 콜론( :
)을 사용하여 저장하려는 값 (1.78)을 저장하려는 식별자("하울")와 구분합니다. 이러한 식별자를 key
라고하며 이를 사용하여 사전에서 데이터를 다시 읽을 수 있습니다.
heights["서근"]
참고 : type annotations 을 사용할 때 사전은 식별자와 값 유형 사이에 콜론( :
)이 있는 대괄호 안에 작성됩니다.
예를 들어 [String: Double]
/ [String: String]
.
딕셔너리와 배열의 차이??
딕셔너리와 배열은 둘 다 하나의 변수에 많은 데이터를 저장하는 방법이지만 서로 다른 방법으로 저장합니다.
딕셔너리를 사용하면 추가하려는 항목을 식별하는 "키" 를 선택할 수 있지만, 배열은 각 항목을 순차적으로 추가합니다.
예를들어 Array
인덱스 [7]이 사용자의 국가를 의미한다는 것을 기억하려고 하기보다, user["country"]
라고 쓰는 것이 훨씬 더 편리합니다.
세트와 마찬가지로 딕셔너리는 특정 순서로 항목을 저장하지 않으므로 빠른 검색을 위해 항목을 저장하는 방식을 최적화합니다.
따라서 user
["country"]
라고 호출을 하면 내부에 1000개의 항목이 있는 사전이 있어도 해당 키(또는 nil
)에 있는 항목을 즉시 반환합니다.
예시
var roles = ["captain": "Mal", "engineer": "Kaylee"]
let scores = ["Sophie": 100]
잘못된 예시
let location = ("road": "Park Lane", "city": "Cardiff")
Dictionary TEST # 1 : 문제를 풀려면 이곳을 클릭해주세요.
딕셔너리 기본값
존재하지 않는 키(nil
)를 사용하여 딕셔너리에서 값을 읽으려고하면 Swift는 nil
을 돌려줄것 입니다. 누락 된 키를 요청하는 경우 사용할 기본값을 사전에 제공할 수 있습니다. 이것을 증명하기 위해 두 사람이 좋아하는 아이스크림 디셔너리를 만들어 보겠습니다.
let favoriteIceCream = [ "서근": "초콜릿", "포뇨": "바닐라" ]
서근이 가장 좋아하는 아이스크림을 다음과 같이 읽을 수 있습니다.
favoriteIceCream["서근"]
하지만 하울에게 가장 좋아하는 아이스크림을 읽으려고 하면 nil
이 반환됩니다. 이는 Swift에는 해당 키에 대한 값이 없음을 의미합니다.
favoriteIceCream["하울"]
디셔너리에 "Unknown"의 기본값을 지정하여이 문제를 해결할 수 있습니다. 이렇게 기본값을 정해주면 '하울'에 대한 아이스크림이 없을 때 nil
이 아닌 "Unknown"이 반환됩니다.
favoriteIceCream["하울", default: "Unknown"]
딕셔너리에 기본값이 있는 이유는??
딕셔너리에서 값을 읽을 때마다 값을 되찾거나 nil
을 되돌릴 수 있습니다. 해당 키에 대한 값이 없을 수도 있습니다. 값이 없으면 코드에 문제가 발생할 수 있습니다. 특히 누락된 값을 안전하게 처리하기 위해 기능을 추가해야 하기 때문에 사전 기본값이 입력됩니다.
예를 들어 학생의 시험 결과를 저장하는 딕셔너리를 만들어 보겠습니다.
let results = [ "영어": 100, "프랑스어": 85, "러시아어": 75 ]
보시다시피, 학생 은은 세 가지 시험에 응시하고 영어, 프랑스어 및 러시아어에서 100점, 85점, 75점을 기록했습니다. 학생의 러시아어 점수를 읽고 싶다면 우리가 원하는 것에 따라, 어떻게 해야 하는지에 따라 달라집니다.
- 누락된 값이 학생이 시험에 실패했음을 의미하는 경우 기본값 0을 사용하여 항상 정수를 반환할 수 있습니다.
- 누락된 값이 학생이 아직 시험을 치르지 않았음을 의미하는 경우 기본값을 건너뛰고 대신 nil 값을 찾아야 합니다.
따라서 사전으로 작업할 때 항상 기본값이 필요한 것은 아니지만 기본값을 정해야 할 때는 쉽습니다.
let historyResult = results["history", default: 0]
예시
let planets = [1: "Mercury", 2: "Venus"]
let venus = planets[2, default: "Planet X"]
let books = ["Austen": "Pride and Prejudice"]
let dickens = books["Dickens", default: "Unknown"]
잘못된 예시
let ships = ["Star Trek", "Enterprise"]
let enterprise = ships["Star Trek"] //이것은 배열입니다.
let ratings = [1: "Bad", 2: "OK", 3: "Good"]
let rating = ratings["2"] //Int값을 줘야하는데 "String"값을 줬습니다.
let users = ["Taylor", "Taylor Swift"]
let taylor = users["Taylor", default: "Anonymous"] //이것은 배열입니다.
딕셔너리의 선언과 생성
// 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:)
메서드를 사용합니다. 키에 해당하는 값이 제거된 후 반환됩니다.
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
Dictionary TEST # 2 : 문제를 풀려면 이곳을 클릭해주세요.
읽어주셔서 감사합니다🤟
'SWIFT > Grammar' 카테고리의 다른 글
Swift : 기초문법 [열거형 - Enum] (1) | 2021.02.19 |
---|---|
Swift : 기초문법 [Empty Collections] (0) | 2021.02.19 |
Swift : 기초문법 [Array vs Set vs Tuple] 간단 비교 (0) | 2021.02.19 |
Swift : 기초문법 [튜플 - TUPLES] 배열과의 차이점 (1) | 2021.02.18 |
Swift : 기초문법 [세트(SET)] (3) | 2021.02.18 |