Swift

Dictionary

dion_K 2020. 11. 20. 22:59
728x90

안녕하세요:)

 

오늘은 Dictionary에 대해서 알아보도록 하겠습니다.

 

1. Dictionary

  • [Key: Value, Key: Value,...] Key와 Value가 한 쌍의 요소입니다.
  • 키는 유일한 값을 가져야 하고, 값은 다른 값과 중복되도 괜찮습니다.
  • Dictionary는 정렬되어 있지 않습니다.
  • 키의 자료형이 같아야 하고 값의 자료형이 모두 같아야 합니다.
  • Key를 통해서 Value에 접근할 수 있습니다.
  • : 으로 키와 값을 구분합니다.
var dict = ["A": "Apple", "B": "BMW", "C": "CJ"]
//[키: 값] 형식으로 저장됩니다.

형태는 이런 식으로 구성됩니다.

이제 문법과 딕셔너리를 만드는 법을 알아보겠습니다.

let dict: Dictionary<String, String> // 정식 문법
let dict2: [String: String] // 단축 문법, 단축 문법을 더 많이 사용합니다.

// 빈 딕셔너리 생성
let emptyDict = Dictionary<String, String>()
let emptyDict2: [String: String] = [:]
let emptyDict3 = [String: String]()

<요소 접근>

 

요소를 접근할 때는 키를 통해서 값에 접근해야 합니다.

var dict = ["A": "Apple", "B": "BMW", "C": "CJ", "D": "Discovery"]

dict.count // 4, 저장된 요소의 갯수를 확인하는 방법입니다.
dict.isEmpty // 딕셔너리가 비어있는지 확인하는 방법입니다.

dict["A"] // Apple
dict["E"] // nil, 없는 키에 접근하면 nil이 리턴됩니다.
dict["E", default: "Hi"] // E에 기본값을 지정하는 방법입니다.

키를 배열로 값을 배열로 만드는 방법을 알아보도록 하겠습니다.

배열 생성자로 만들면 배열로 바꿀 수 있습니다.

Array(dict.keys).sorted() // ["A", "B", "C", "D"]
Array(dict.values).sorted() // ["Apple", "BMW", "CJ", "Discovery"]

<요소 추가>

var world = [String: String]()

world["A"] = "Australia"
world["B"] = "Belgium"
world // ["A": "Australia", "B": "Belgium"]

// 이미 존재하는 키로 새로운 값을 추가하면 어떻게 될까요?
world["B"] = "Bulgaria"
world // ["A": "Australia", "B": "Bulgaria"]
// 값이 새로운 값으로 변경되었습니다.

world.updateValue("Canada", forKey: "C")
world // ["C": "Canada", "B": "Bulgaria", "A": "Australia"]

<요소 삭제>

var world = ["C": "Canada", "B": "Bulgaria", "A": "Australia"]

world["A"] = nil
world // ["B": "Bulgaria", "C": "Canada"]

world["B"] = nil
world // ["C": "Canada"]

world.removeValue(forKey: "C") // Canada
world // [:]

world.removeAll() // 모든 요소가 삭제되고 메모리 공간까지 삭제됩니다.
world.removeAll(keepingCapacity: true) // 메모리 공간을 유지하고 모든 요소를 삭제합니다.

<요소 비교>

var worldA = ["C": "Canada", "B": "Bulgaria", "A": "Australia"]
var worldB = ["C": "canada", "B": "bulgaria", "A": "australia"]

worldA == worldB // false
worldA != worldB // true

worldA.elementsEqual(worldB) { (lhs, rhs) -> Bool in
    return lhs.key.caseInsensitiveCompare(rhs.key) == .orderedSame && lhs.value.caseInsensitiveCompare(rhs.value) == .orderedSame
    } // 대소문자 구분 없이 키와 값을 비교합니다. 잘못된 코드!!

키와 값을 대소문자 구분 없이 비교했는데 false로 결과가 나왔습니다. 어 ?? 뭐지..

한 번 더 해보겠습니다. 이번에는 true로 나왔습니다.

왜 이렇게 나올까요?

그 이유는 딕셔너리는 정렬되어 있지 않습니다. 그래서 이 코드는 잘못된 코드입니다.

그럼 비교할 때는 어떻게 해야 할까요?

답은 키를 정렬한 후 비교해야 합니다.

let akeys = worldA.keys.sorted()
let bkeys = worldB.keys.sorted()
// 키를 정렬했으니 비교해보겠습니다.

akeys.elementsEqual(bkeys) { (lhs, rhs) -> Bool in
    guard lhs.caseInsensitiveCompare(rhs) == .orderedSame else {
       return false // 두 키가 다르면 false를 리턴!
    }
    
    guard let lValue = worldA[lhs], let rValue = worldB[rhs], lValue.caseInsensitiveCompare(rValue) == .orderedSame else {
        return false // 두 값이 다르면 false를 리턴!
    }
    
    return true
} // true

정리를 해보면 우선 두 딕셔너리를 비교할 때는 키를 정렬해야 합니다.

키를 정렬한 후 값을 비교해야 합니다.

728x90