Swift

Swift | Collection (컬렉션)에 관하여 3 - Dictionary

ziziDev 2024. 5. 11. 16:43
반응형

안녕하세요!

Collection 3번째!!시간

 

오늘은 Dictionary

에 대해서 알아보고자 합니다

 

Dictionary

배열과 마찬가지로 딕셔너리는 처음부터 필요한 모든 데이터를 입력한 상태로 사용하는 경우가 많지 않아요

 

대부분 빈 딕셔너리를 선언(초기화)하고 하나씩 추가하는 방식이랍니다

 

 

설명처럼 고유 키와 그에 대응하는 값을 가지고 있는 한쌍의 자료형을 볼 수 있습니다

Hashable하여 Set과 마찬가지로 저장되는 형식을 가지고 있답니다

Hashable이 궁금하시다면 

Set 게시물로 가셔서 한 번 정독 해주세요!

 

 하지만 여기서 짧게 이야기하자면 

그래서 해시 테이블에서 각 항복은 문자열 숫자와 같은 해시 가능한 유형으로

해당 키를 사용하여 임의의 객체일 수 있느 해당값을 검색하는데요

 

 Hash value를 가지고 접근하여 값에 접근하기 때문에 배열처럼 순서가

없습니다!

 

딕셔너리 특징

 

하나의 키는 하나의 데이터에만 연결이 되어야합니다

키값이 중복되어서는 

XXX

 

키값이 중복될 수 없기 때문에 만약 중복해서 넣게된다면

아이템 추가가 아니라 수정이 이루어져서

기존 키에 연결된 데이터가 제거되어 집니다!

 

저장할 수 있는 데이터 타입이 제한은 없지만

하나의 딕셔너리에는 하나의 데이터 타입만 정의 할 수 있답니다

위 예제는 HTTP응답 코드 및 관련 메시지 딕셔너리로 만들어보았습니다

 

딕셔너리 아이템에는 Set처럼 순서가 없지만

key에는 내부적으로 순서가 있기 때문에 for-in 구문을 이용하여 탐색이 가능하답니다

 

키의 타입은 제한이 없지만 hash 연산이 가능한 타입이어야 한다는점!

 

이렇게 key값을 대입하게되면 value값이 나오는것을 코드로 볼 수 있습니다

 

 

 

이렇게 글로만 보면 이해가 어려울 수 있으므로 코드를 보면서 이해해봅시다 :)

 

딕셔너리의 타입의 표기

 

위 첫 번째는 선언과 동시에 초기화가 된답니다

아래쪽은 초기값이 없으므로 옵셔널 형태도 아니고 그냥 타입만 명시해줬을 뿐입니다

 

만약 초기화는 어떤식으로 해야하는거야??!!

 

딕셔너리의 초기화

 

 

위와같이 선언하게되면 초기화가 됩니다 :)

 

명시와는 조금 다르죠?

 

대입연산자를 사용하여서 인스턴스를 생성하는걸 볼 수 있습니다

 

<> 안에 key, value 한 쌍으로 들어가는데 

다양한 자료형이 들어갑니다

앞에서 배운 것들을 더해서 딕셔너리가 안에 한 번 더 들어갈 수도 있으며

클래스 구조체 정말 무궁무진하게 들어갈 수 있다고 말해주고 싶습니다

:)

 

 

이런식으로 타입을 명시하고 생성을 할 수 있습니다

첫번째 capital에서 ()를 넣지 않으면 명시만 하는것이며

변수명을 지을 때 부터 생성을 하고 있는걸 확인할 수 있습니다

하지만

만약 ()가 없는

capital = Dictionary()로 통해서 초기화를 할 수 있답니다 :)

 

그리고 딕셔너리는 유추와 빈배열을 바로 넣을 수 있답니다

 

딕셔너리 아이템 추가 및 다양한 활용

 

선언 + 초기확가 완료되면

딕셔너리 데이터를 추가하여 활용을 해야할 차례인데요

단순하게 추가하는 방법은 배열과 비슷합니다

 

그대신 고유 키값을 가져야하기 때문에

키값을 [key] 기재하고 =다음에 value값을

입력하면 됩니다

 

이렇게 하나씩 키값을 추가하게되면

늘어나는걸 확인할 수 있습니다

 

그리고 배열처럼

정렬과 for문을 이용해서 출력이 가능합니다

 

또한 key값이 없으면 Error가 발생할 수 있기에

 

옵셔널 바인딩으로 없으면 nil값이 나옵니다

 

optional은 추후에 정리하도록 하겠습니다 :)

 

그리고 딕셔너리에 값을 할당하는 데 사용되는 메서드가 있습니다

 

UpdateValue(_:forKey:)

거두절미하고 코드로 확인해보고자 합니다 :)

여기서 중점적으로 봐야하는건 없는 키값에 updateValue를 하게된다면

return value는 nil 이지만

딕셔너리에 추가된것을 확인할 수 있습니다

 

Dictionary는

append 메서드를 제공하지 않는답니다 :)

딕셔너리는 Set과 동일하게 순서가 없기 때문에

updateValue로 통해서 확장하고 있답니다

 

dictionary 는 for 구문을 통해서

key, value값을 출력할 수 있습니다

 

이렇게 임의 상수나 와일드카드 패턴을 사용하지 않고

이렇게 코드를 작성하는 방법도 있습니다

 

딕셔너리 비교

배열과 동일하게

모두가 동일해야합니다

순서는 상관없으며 내부의 키값과 벨류값의 쌍이 동일해야합니다

 

배열과 동일하게 딕셔너리도 삭제가 가능합니다

아까 겹쳤던 KOR / KR이 있었으니 둘 중 하나를 삭제하도록 합시다!

 

 

삭제에 대해서는

배열과 비슷하다는걸 알 수 있습니다

 

딕셔너리는 key값은 단순한 자료형이 들어가고 value에 여러가지가

들어가는데

초반에 이야기했듯이

배열 / 클래스 / 구조체 / 딕셔너리

다양한 활용이 가능한 녀석이다

 

게임에서 정말 다양하게 사용했었다

 

 

다음에 한 번 더 심화적으로 다루고

정리하겠습니다

아직 클래스와 구조체를 정리하지 않았기 때문에..

 

마지막으로 Ojbective-C에서 사용하는 NSDictionary가 있는데

Dictionary와 연결이 가능합니다

무슨말인가??

즉 Ojbective-C와 Swift 간에 데이터를 주고받을 수 있는

브릿지 역할을한답니다

 

여기서 NSDictionary란?

 

Ojbective-C나 Swift에서 사용할 수 있는 Foundation 프레임워크에 포함된 클래스 입니다

Objective-C에서는 주로 클래스를 사용하여 데이터를 그룹화하고 전달을 합니다

 

Swift(Dictionary) -> Ojbective-C(NSDictionary)

Ojbective-C(NSDictionary) -> Swift(Dictionary)

가능하다는 사실!

 

하지만 처음 복사하고 각 요소에 대한 첫 번째 접근을 할 때 O(n)시간이 걸릴 수 있습니다

O(n)시간은 요소의 개수에 비례하는 만큼 시간이 걸린다는 뜻입니다

 

copy(with:)메서드를 호출하게되면

불변한(copy on write)복사를 수행하여

불변한 인스턴스의 경우에는 O(1)의 시간이 수행하게됩니다

하지만 데이터가 변경 가능한 경우 즉 NSDictionary가 변경되거나 수정되는 경우에 새로운 사본을 만들어야하기 때문에

O(n)만큼의 시간 소요가 될 수 있습니다 

하지만 또 다시 접근 했을 때 O(1)시간이 걸리겠지만 

이건 데이터가 변경되지 않았을 때를 말하며

만약 여기서 또 변경이 되었을 때 또다시 O(n)시간이 소요됩니다

 

 

//object-C언어
NSDictionary *objcDictionary = @{@"key1": @"value1", @"key2": @"value2", @"key3": @"value3"};

// Swift으로 변환
NSError *error = nil;
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:objcDictionary options:0 error:&error];
NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];

 

// Objective-C에서 전달받은 JSON 문자열
let jsonString = "{\"key1\":\"value1\",\"key2\":\"value2\",\"key3\":\"value3\"}"

// JSON 문자열을 Swift의 Dictionary로 변환
guard let jsonData = jsonString.data(using: .utf8),
      let swiftDictionary = try? JSONSerialization.jsonObject(with: jsonData, options: []) as? [String: String] else {
    print("JSON 데이터를 Dictionary로 변환할 수 없습니다.")
    return
}

// 변환된 Dictionary를 사용
print(swiftDictionary["key1"]) // 출력: Optional("value1")

 

 

*혹시 틀린 부분이 있으면 알려주세요! 감사합니다*

반응형