본문 바로가기

iOS/Swift

Swift) Dictionary - 자주 사용하는 메서드

 

 

 

 

안녕하세요 :) 소들입니다

이번 포스팅에선 딕셔너리를 사용할 때 알아두면 편한 메서드들을 좀 정리해보려고 해요!!!

원래 설명충이긴 한데, 이번 포스팅만큼은 단순 명료하게 가겠슴니다!!

(물론 설명할 게 있는 부분은 설명충임 :))

 

모든 포스팅은 편의 말투로 합니다~!!

 

.

.

.

자 먼저..!!!

Swift의 딕셔너리 특징에 대해서 간!!!딴!!!!히!!!! 먼저 알고 가겠움 :)

 

 

🔸Key : Value가 함께 저장되는 자료구조이다

🔸정렬되지 않은 컬렉션이다

(따라서 딕셔너리를 print할 경우, 삽입 순서에 상관 없이 뒤죽박죽 나온다)

🔸값은 중복 가능하지만, 키는 중복되면 안 된다

🔸Swift는 형식에 민감쓰 하기 때문에, 모든 Key의 자료형은 같아야 하고, 

마찬가지로 모든 Value의 자료형도 같아야 한다

 

 

끄...읕... 🌝 이 정돈 기본이니 알아둡시다....... :D

이제 딕셔너리에서 사용하는 메서드에 대해 다루겠음 :)

아 참고로, 딕셔너리도 배열과 같은 Collection Type이고, 때문에

구조체로 Stack에 저장됨! 다만, NSDictionary란 클래스도 지원함(Objective-C)

 

 

 

 

 

1. 딕셔너리 생성하기

 

 

// 1. 타입 추론으로 생성하기
var dict1 = ["height"165"age" : 100]
var dict2 = [:]                                         // error! 타입 추론으론 빈 딕셔너리 생성 불가
 
 
// 2. 타입 Annotation으로 생성하기
var dict3: [StringInt= [:]                          // 빈 딕셔너리 생성
var dict4: [StringInt= ["height"165"age" : 100]
 
 
// 3. 생성자로 생성하기
var dict5 = Dictionary<StringInt>()                   // :이 아닌 ,로 명시
var dict6 = [StringInt]()
 

 

 

보통  간편한 1번이나 2번의 방법을 많이 사용함!!!

나 같은 경우엔 Type Annotation을 좋아해서 2번을 많이 씀 :)

 

녀러분 Swift는 머라거?? 타입에 굉~~~~장히 민감한 언어임!!! 

  선언과 동시에 Type을 꼭 명시하거나 추론할 수 있게 해주어야 하고,

해당 Type으로 된 값만 딕셔너리에 저장할 수 있음!!!

 

따라서 만약 난 딕셔너리 한 개에 여러 타입의 Value를 저장하고 싶은데???

혹은 난 런타임 시점에 타입을 알 수 있는데????라고 할 수 있잖음??

Key 값의 Type Any로 선언하거나, Objective-C의 클래스인 NSDictionary를 사용하면 됨

 

 

// 4. 여러 타입을 저장하는 딕셔너리 생성하기
var dict7: [StringAny= ["name""Sodeul""age"100]
var dict8: NSDictionary = ["name""Sodeul""age"100]

 

 

 Value 같은 경우, 배열 때와 마찬가지로 Any라는 자료형을 쓰면 됨!!!

호옹..? 근데 나는 Key 값도 여러 타입 받고 싶은데..? 해서 Any로 선언할 경우,

다음과 같은 에러를 볼 수 있음

 

 

 

 

Any가 Hashable 프로토콜을 준수하지 않는단 말임..!

이 포스팅을 보면 알겠지만, 딕셔너리는 Key 값을 해시한 것을 토대로 데이터를 저장하기 때문에

딕셔너리의 Key 값은 아무나 올 수 없음!!!!!!!!! 무조건 Hashable이란 프로토콜을 준수하는 자료형만 Key 값에 올 수 있음

때문에 Any도 올 수 없는 것이고, 만약 커스텀 자료형을 만든다면, Hashable 프로토콜을 준수해야만,

Dicitonary의 Key 값으로 사용할 수 있음 :)

 

배열에서도 말했듯, Any를 남발하는 것은 정적 바인딩 언어인 Swift를....

동적 바인딩 시키는 것이기 때문에,,,,, 타입에 민감한 Swift를 웬만해선 지켜줍시다.. :)

 

 

 

 

2. 딕셔너리 갯수 확인하기

 

 

var dict1 = ["height"165"age" : 100]
 
let countInt = dict1.count            // 딕셔너리 갯수 확인 : 3
let isEmptyBool = dict1.isEmpty       // 딕셔너리 비었는지 확인 : false

 

 

만약 딕셔너리가 비었는지를 확인하고 싶다면

dict1.count == 0 이 구문보단, dict1.isEmpty를 사용합시다 :)

 

 

 

 

3. 딕셔너리 요소에 접근하기

 

 

var dict1 = ["height"165"age" : 100]
 
// 1. 반환 값 - Optional Type
let height = dict1["height"]                     // Optional(165)
let weight = dict1["weight"]                     // nil
 
// 2. 반환 값 - Non Optional Type
let height = dict1["height", default: 150]       // 165
let weight = dict1["weight", default: 200]       // 200

 

 

딕셔너리의 경우, Subscript로 요소에 접근하면

기본 반환값이 Optional Type이기 때문에 (해당 Key 값이 없을 때를 대비)

따라서, 만약 Optional Type이 싫다!!!!!!하면 default 값을 직접 명시하면 됨!

그럼 반환 값이 Non-Optional Type임!

 

 

 

 

4. 딕셔너리에 요소 추가하기

 

 

var dict1 = ["height"165"age" : 100]
 
// 1. Subscript로 추가하기
dict1["weight"= 100                                // 해당 Key가 없다면, 추가 (insert)
dict1["height"= 200                                // 해당 Key가 있다면, Value 덮어쓰기 (update)
 
// 2. updateValue(:forKey)
dict1.updateValue(100, forKey: "weight")             // 해당 Key가 없다면, 추가하고 nil 리턴 (insert)
dict1.updateValue(200, forKey: "height")             // 해당 Key가 있다면, Value 덮어쓰고 덮어쓰기 전 값 리턴 (update)

 

 

Subscript의 경우, insert인지 update인지 알 수 없지만,

updateValue의 경우, 리턴 값을 통해 insert인지 update인지를 알 수 이씀!

(참고로 Insert와 upsert를 상황에 따라 해주는 것을 upsert라고 함)

 

 

 

 

5. 딕셔너리에 요소 삭제하기

 

 

var dict1 = ["height"165"age" : 100]
 
// 1. Subscript로 삭제하기 (nil 대입하기)
dict1["weight"= nil                              // 해당 Key가 없어도 에러 안남
dict1["height"= nil                              // 해당 Key가 있다면, 해당 Key-Value 삭제
 
// 2. removeValue(forKey:)
dict1.removeValue(forKey: "weight")                // 해당 Key가 없다면, nil 반환
dict1.removeValue(forKey: "age")                   // 해당 Key가 있다면, 해당 Key-Value 삭제 후 삭제된 Value 반환 : Optional(100)
 
// 3. removeAll() : 전체 삭제하기
dict1.removeAll()
 

 

 

 

6. Key, Value 나열하기

 

 

var dict1 = ["height"165"age" : 100]
 
// 1. Key 모두 나열하기
dict1.keys                         // "height, "age"
dict1.keys.sorted()                // "age", "height
 
// 2. Value 모두 나열하기
dict1.values                       // 165, 100
dict1.values.sorted()              // 100, 165

 

 

정렬도  가능!!!!!!!!!!!!

keys, values는 찍을 때마다 다르게 나올테니 당황 노노

(딕셔너리는 정렬되지 않는 Collection Type)

 

 

 

 

7. 딕셔너리 비교하기

 

 

var dict1 = ["height"165"age" : 100]
var dict2 = ["height"165"age" : 100]
var dict3 = ["Height"165"Age" : 100]
var dict4 = ["name""sodeul""address" : "Suwon"]
 
dict1 == dict2              // true
dict1 == dict3              // false (대소문자 다름)
dict1 == dict4              // false (모든 Key-Vlaue 다름)

 

 

비교 연산자로 비교할 수 있으나, 모든 Key와 Value가 정확히 모두 일치해야만

true가 됨!!!! 대소문자도 비교하기 때문에, dict1과 dict3은 다른 딕셔너리임!!!

 

 

 

 

8. 딕셔너리 요소 검색하기

 

 

var dict1 = ["height"165"age" : 100]
 
let condition: ((StringInt)) -> Bool = {
    $0.0.contains("h")
}
 
// 1. contains(where:)  : 해당 클로저를 만족하는 요소가 하나라도 있을 경우 true
dict1.contains(where: condition)                   // true
 
// 2. first(where:)     : 해당 클로저를 만족하는 첫 번쨰 요소 튜플로 리턴 (딕셔너리는 순서가 없기 때문에, 호출할 때마다 값이 바뀔 수 있음)
dict1.first(where: condition)                      // Optional((key: "height", value: 165))
 
// 3. filter            : 해당 클로저를 만족하는 요소만 모아서 새 딕셔너리로 리턴
dict1.filter(condition)                            // ["height": 165]

 

 

자, 여기서 중요한 거!!!!!!!!!! 딕셔너리 요소 검색할 때는

클로저를 이용해서 검색하는데,

 

이때 클로저의 파라미터 타입은 내가 지정한 딕셔너리의 타입을 갖는

튜플이어야 하고!! 반환 타입은 무조건 Bool이어야 함!!!!!!!!!1

만약 [String: String] 타입의 딕셔너리라면,

 

((String, String)) -> Bool

 

클로저를 이렇게 작성 하셔야 함..........:D

+ 만약 딕셔너리 순회(for - in, forEach) 등에 대해 알고 싶으신 분은

이 포스팅을 참조해주센~~

 

 

.

.

.

딕셔너리를 사용할 때 어쩌면 필수고 어쩌면 알아두면 좋은 메서드들 정리 끝 :)

또한 더 많은 메서드들을 알게되면 추가 할게영 :D

읽으시는 모든 분께 도움이 됐길 ~.~

 

잘못된 내용, 피드백, 궁금증은 언제나 댓글 주세요 💩

그럼 프젝하러 가야해서 20,000

 

 



Calendar
«   2024/03   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
31
최근 댓글
Visits
Today
Yesterday