본문은 야곰 아카데미 커리어 스타터 캠프를 통해 학습한 내용을 회고한 글입니다.
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
반복문을 통해 딕셔너리 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
https://2unbini.github.io/%F0%9F%93%82%20all/swift/dictionary-sorted/
'YAGOM CAREER STARTER' 카테고리의 다른 글
[TIL] 20230105: Type Casting, Singleton, 반환타입, Nil 반환 (0) | 2023.01.06 |
---|---|
[TIL] 20230104: KVO (0) | 2023.01.04 |
[TIL] 20230102: MVC, Initialization, 쥬스 메이커, 연결 리스트 (0) | 2023.01.03 |
[TIL] 20221230: Computed Property, Static (0) | 2022.12.31 |
[TIL] 20221229: H.I.G, Extension, Enum (0) | 2022.12.29 |