나의 발자취

스위프트 컬렉션(2) 딕셔너리 본문

앱 개발/iOS

스위프트 컬렉션(2) 딕셔너리

달모드 2022. 5. 25. 23:06

딕셔너리의 키는 hashable해야한다. = 유일성이 보장되어야한다. (내부적으로 순서대로 존재하지 않기때문에 유일성을 가진 매커니즘을 가져야지만 가능)

 

참고: 해쉬

스위프트의 기본 타입은 모두 hashable하다. (개발자 지정 타입은 hashable 하지 않음) = 해시함수에 input으로 쓰일 수 있는 타입이다. = 해시함수를 사용해서 유일한 값으로 변환이 가능하다. = 유효성을 보장하고 검색 속도가 빠르다(배열보다 훨씬 빠르다)

 

딕셔너리 타입 표기

 

// 단축문법

var words: [String: String] = [:]

// 정식문법

let words1: Dictionary<Int, String>

 

딕셔너리 생성

 

let emptyDic1: Dictionary<Int, String> = [:]

let emptyDic2 = Dictionary<Int, String>()

let emptyDic3 = [Int: String]()

 

 

//var dictFromLiteral = [:]    // 타입 정보가 없으면 유추할 수가 없다.

var dictFromLiteral = ["1": 1, "2": 2]

 

dictFromLiteral = [:]    // 이미 위에서 타입을 정의했다면, 아래에서 빈 값으로 넣는 것은 괜찮음

 

딕셔너리 기본 기능

dic = ["A": "Apple", "B": "Banana", "C": "City"]

 

dic.count   // 0

dic.isEmpty // true

 

// contains 함수가 존재하긴 하나, 뒤에서 배울 클로저의 내용을 알아야함

// dic.contains(where: <#T##((key: String, value: String)) throws -> Bool#>)

 

dic.randomElement()      // Named Tuple 형태로 리턴

 

딕셔너리 요소 접근

// 딕셔너리

dic = ["A": "Apple", "B": "Banana", "C": "City"]

dic["A"]        // nil의 가능성 -> String?(옵셔널)

 

 

if let a = dic["A"] {    // 옵셔널 바인딩

    print(a)

} else {

    print("Not found")

}

 

 

딕셔너리 요소 찾기

// 딕셔너리는 값만 따로 검색하는 방법은 제공하지 않음. ⭐️

// 서브스크립트 문법으로 "키"를 전달

 

 

// 참고 (잘 사용하지는 않음)

dic["S", default: "Empty"]       // nil이 발생할 확률이 없음

// 자료가 없으면 기본값을 리턴하는 문법  ===> 리턴 String

 

// 컬렉션으로 하고 싶을 때

dic.keys

dic.values

 

// 배열으로 하고싶을 때

dic.keys.sorted()

dic.values.sorted() 

 

 

 

for key in dic.keys.sorted() {     // 오름차순 정렬  ===> "return 배열" 배열이 됨

    print(key)

}

 

 

 

 

 

 업데이트 (update) - 삽입하기 / 교체하기 / 추가하기

: 딕셔너리에는 insert/replace/append가 없다.

 

words = [:]   // 빈 딕셔너리 생성

 

 

 

words["A"] = "Apple"   // 애플로 다시 바꾸기

words["B"] = "Banana"  // 동일한 키가 없으면 ===> 추가하기

words["B"] = "Blue"    // 동일한 키가 있으면 ===> 기존 밸류 덮어쓰기

 

 

 

 

// (정식 기능) 함수 문법 (update + insert = upsert)

words.updateValue("City", forKey: "C")   // 새로운 요소가 추가되면 ==> 리턴 nil

words

 

 

//words = [:]      // 빈 딕셔너리로 만들기

words = ["A": "A"]   // 전체 교체하기(바꾸기)

 

 

 

딕셔너리는 append 함수를 제공하지 않음

// append는 순서가 있는 컬렉션의 끝에 추가하는 개념

// 딕셔너리는 순서가 없기 때문에, update를 통해서 추가

 

 

 딕셔너리 삭제(제거)하기 (remove)

dic = ["A": "Apple", "B": "Banana", "C": "City"]

 

 

// 요소 삭제해 보기

dic["B"] = nil    // 해당요소 삭제

dic["E"] = nil   // 존재하지 않는 키/값을 삭제 -> 아무일이 일어나지 않음(에러아님)

 

 

// 함수로 삭제해보기

dic.removeValue(forKey: "A")   // 삭제후, 삭제된 값 리턴

dic.removeValue(forKey: "A")   // 다시 삭제해보기 ===> nil리턴

 

 

 

 

// 전체 삭제하기

dic.removeAll()

dic.removeAll(keepingCapacity: true)

 

 

딕셔너리의 비교

let a = ["A": "Apple", "B": "Banana", "C": "City"]

let b = ["A": "Apple", "C": "City", "B": "Banana"]

 

 

비교 연산자

a == b   // true

// 딕셔너리는 원래 순서가 없기 때문에, 순서는 상관없음

// (순서 상관없이 무조건 true나옴 - Hashable하기 때문에, 순서 상관없이 비교가능)

a != b   // false

 

 

 

딕셔너리의 활용

// 딕셔너리의 중첩 사용

 

var dict1 = [String: [String]]()        // 딕셔너리 밸류에 "배열"이 들어갈 수도 있다.

 

 

dict1["arr1"] = ["A", "B", "C"]

dict1["arr2"] = ["D", "E", "F"]

dict1

 

//dict1["arr"] = "A"

 

 

 

var dict2 = [String: [String: Int]]()     // 딕셔너리 안에 딕셔너리가 들어갈 수 있다.

 

dict2["dic1"] = ["name": 1, "age": 2]

 

dict2["dic2"] = ["name": 2, "age": 4]

 

dict2

 

 

 

 

 반복문과의 결합

// 딕셔너리 열거해서 프린트 하기

let dict = ["A": "Apple", "B": "Banana", "C": "City"]

 

딕셔너리는 열거하지 않아도, Named 튜플 형태로 하나식 꺼내서 전달

순서가 없으므로, 실행마다 순서가 달라짐 ⭐️

 

 

 

데이터 바구니이기 때문에, 차례대로 하나씩 꺼내서 사용하는 경우가 많을 수 있어서 아래처럼 활용 가능

 

 

for (key, value) in dict {

    print("\(key): \(value)")

}

 

// key만

for (key, _) in dict {

    print("Key :", key)

}

 

// value만

for (_, value) in dict {

    print("Value :", value)

}

 

 

Comments