본문 바로가기
YAGOM CAREER STARTER

[TIL] 20230103: CaseIterable, 반복문을 통해 딕셔너리 key와 value 가져오기

by Rhode 2023. 1. 3.

본문은 야곰 아카데미 커리어 스타터 캠프를 통해 학습한 내용을 회고한 글입니다.

 


for 문을 돌리고 싶어서 여러 가지 방법들을 찾아보았다.

CaseIterable

enum을 배열처럼 사용할 수 있는 프로토콜이다. CaseIterable 타입을 이용할 때, allCases 프로퍼티를 사용하면 그 타입의 모든 case들 컬렉션에 접근할 수 있게 된다. 

enum Dogs: CaseIterable {
    case hodoo
    case yulmoo
    case zandi
}

let dogList = Dogs.allCases
print(dogList)  //[workSpace.Dogs.hodoo, workSpace.Dogs.yulmoo, workSpace.Dogs.zandi]

for dog in dogList {
    print("The name of my dog is \(dog)")
}
//The name of my dog is hodoo
//The name of my dog is yulmoo
//The name of my dog is zandi
enum을 배열처럼 사용해 줄 수 있게 만드는 프로토콜이기 때문에, Dogs에 allCases를 붙여서 새로운 dogList라는 상수를 만들면 그에 대해서는 for문을 돌릴 수 있게 된다.

 

반복문을 통해 딕셔너리 key와 value 가져오기

반복문을 통해 딕셔너리 key와 value를 가져올 수 있다. 

var myDog = ["Rhode": "hodoo", "hyemin": "yulmoo", "euijin": "jandi"]

for (key, value) in myDog {
    print("The name of \(key)'s dog is \(value)")
}
//The name of hyemin's dog is yulmoo
//The name of euijin's dog is jandi
//The name of Rhode's dog is hodoo


for key in myDog.keys {
    print(key)
}
//hyemin
//euijin
//Rhode

for value in myDog.values {
    print(value)
}
//yulmoo
//jandi
//hodoo

주목할 만한 점이 두 가지 있다.

  • key와 value가 도는 순서는 랜덤이다: 나는 Rhode, hyemin, euijin 순서로 키를 넣었는데, 딕셔너리는 순서가 없는 컬렉션이기 때문에 랜덤으로 출력이 되었다.
  • for문을 통해 key와 value에 접근하면 옵셔널이 아니다: 딕셔너리의 key를 통해서 value에 접근하면 기본적으로 옵셔널 값이 나온다. 그렇지만 위 코드에서는 yulmoo, jandi, hodoo가 그대로 나왔다. 

순서대로 출력할 수 있는 방법은 없을까?

딕셔너리를 정렬하려면 sorted()를 사용해주면 된다. 그리고 key로 정렬하는 방법과 value로 정렬하는 방법 두 가지가 있다.

Key를 기준으로 정렬

다음과 같이 표현하여 key로 정렬할 수가 있다.

let sortedMyDog1 = myDog.sorted { (first, second) in
    return first.key < second.key }
print(sortedMyDog1)
//[(key: "Rhode", value: "hodoo"), (key: "euijin", value: "jandi"), (key: "hyemin", value: "yulmoo")]

let sortedMyDog2 = myDog.sorted(by: <)
print(sortedMyDog2)
//[(key: "Rhode", value: "hodoo"), (key: "euijin", value: "jandi"), (key: "hyemin", value: "yulmoo")]

 

그렇지만, 뭔가 순서가 이상하다. Rhode -> euijin -> hyemin 순서이다.

let myDog2 = ["rhode": "hodoo", "hyemin": "yulmoo", "euijin": "jandi"]
let sortedMyDog3 = myDog2.sorted(by: <)
print(sortedMyDog3)
//[(key: "euijin", value: "jandi"), (key: "hyemin", value: "yulmoo"), (key: "rhode", value: "hodoo")]

Rhode의 대문자가 문제가 되었나보다. 대문자를 소문자로 바꾸니 다시 알파베틱한 순서로 정렬이 되었다. 이렇게 정렬을 해 놓고 for문을 돌려서 다시 프린트를 해보자. 

띠용? 에러가 뜬다.

아놔.. [(key: "euijin", value: "jandi"), (key: "hyemin", value: "yulmoo"), (key: "rhode", value: "hodoo")] 라고 쓰여있는 걸 보니.. 이 놈은 딕셔너리가 아니고 딕셔너리의 요소들을 갖춘 배열이다. 쩝.

결국은 딕셔너리를 순차적으로 만들어서 출력할 수 있는 방법은 없는 듯 하다.

그래도 기왕 알아본 김에 value를 기준으로 정렬하는 법도 알아보자.

 

Value를 기준으로 정렬

let sortedMyDog4 = myDog2.sorted { (first, second) in
    return first.value < second.value
}
print(sortedMyDog4)
//[(key: "rhode", value: "hodoo"), (key: "euijin", value: "jandi"), (key: "hyemin", value: "yulmoo")]

요렇게 해주면 된다. 방금까지 배웠던 두 가지 방법을 통해서 우선적으로 value로 정렬하고 value가 같으면 key로 정렬하는 방법도 구현해낼 수 있다.

let myDog3 = ["rhode": "hodoo", "hyemin": "yulmoo", "euijin": "jandi", "amugae": "hodoo", "kimzzizzigae": "hodoo"]
let sortedMyDog5 = myDog3.sorted { (first, second) in
    if first.value == second.value {
        return first.key < second.key
    }
    return first.value < second.value
}
print(sortedMyDog5)
//[(key: "amugae", value: "hodoo"), (key: "kimzzizzigae", value: "hodoo"), (key: "rhode", value: "hodoo"), (key: "euijin", value: "jandi"), (key: "hyemin", value: "yulmoo")]

아무개와 김찌찌개가 호두라는 강아지와 산다고 해봤다. 이 때, value로 정렬을 하자니 호두가 세마리나 된다. 그래서 반려인들 이름으로 또 알파베틱한 순서로 정렬해줬다. 그래서 아무개-호두 -> 김찌찌개-호두 -> 로데-호두 -> 잔디 -> 율무 이 순서가 나오는 것이다. 반대로 우선적으로 key로 정렬하고 key가 같으면 value로 정렬하는 방법도 있을까? 

정신 차려라 휴먼. 딕셔너리에 같은 키값을 중복으로 둘 수 없으니 그런 일은 일어나지 않는다.

 

 

 

참고

https://jellysong.tistory.com/91

 

[Swift] Collection Type - 딕셔너리(Dictionary), 반복문, key/value 기반 정렬

안녕하세요! 이번 포스팅은 Swift 데이터구조와 알고리즘 책의 2장 스터디 중 두번째 핵심 내용인 Collection Type 에 대한 내용입니다. Array (배열), Dictionary (딕셔너리, 사전형), Set (세트), Tuple(튜플)

jellysong.tistory.com

https://2unbini.github.io/%F0%9F%93%82%20all/swift/dictionary-sorted/

 

스위프트 딕셔너리 정렬, Swift Dictionary sorted()

딕셔너리 정렬하기

2unbini.github.io