cchanmi
[Swift] Dictionary, Set 들어온 순서대로 값 출력하기 본문
Dictionary와 Set은 내부적으로 hashTable로 구성되어 있기 때문에, 순서가 보장되지 않죠.
가끔 Dictionary와 Set으로 값을 찾으면 딱 좋은 상황인데, 값이 들어온 순서대로 출력해야 하는 상황을 겪는다면 어떻게 해야 할까요?
그럴 때마다 항상 Dictionary와 Set을 포기했었는데, 이번에 원하는대로 출력할 수 있는 로직을 구현해 보게 되어서 기록해 두려고 합니다. ㅎㅎ
해당 함수는 입출력으로 [1, 2, 3, 3, 3, 3, 4, 4]라는 배열을 주고 있습니다.
여기서 중복되는 배열의 값일 경우, 그 중복값을 count 하여 출력해 주고자 합니다.
단, 먼저 나온 순서대로 출력하고자 합니다.
예를 들면 위의 입출력에서는
Dicrionary를 이용한 로직
func solution_version_Dictionary(_ array: [Int]) -> [Int] {
var dic = [Int:(order: Int, count: Int)]()
func sameValueCount(_ array: [Int]) {
var order = 1
for i in 0..<array.count {
let number = array[i]
if let temp = dic[number] {
dic[number] = (order: temp.0, count: temp.1+1)
continue
}
dic[number, default: (0, 0)] = (order: order, count: 1)
order += 1
}
}
sameValueCount(array)
var resultArray = dic.filter { $0.value.1 > 1 }.sorted(by: { $0.value.order < $1.value.order}).map{ $0.value.count }
return resultArray.isEmpty ? [-1] : resultArray
}
print(solution_version_Dictionary([1, 2, 3, 3, 3, 3, 4, 4])) // [4, 2]
print(solution_version_Dictionary([3, 2, 4, 4, 2, 5, 2, 5, 5])) // [3, 2, 3]
print(solution_version_Dictionary([3, 5, 7, 9, 1])) // [-1]
Int 타입의 key를 가지고, value로 튜플 타입(order, count)의 Int 값들을 담을 수 있는 dictionary를 만들어 두었구요.
순서 변수인 order를 하나 만들어 줍니다.
dictionary에 해당 key에 접근하였을 때, value가 있다면, value.order는 증가할 필요가 없고, 중복 횟수는 +1을 해 줍니다.
그리고 다음 순서로 값을 저장해 주기 위해 order += 1을 해 주고요
반대로 dictionary를 통해 해당 key에 접근하였지만, value가 없어서 nil 값이 나오는 경우는 value.order에 해당 순서인 order 값을 넣어 주고, count는 1을 넣어 줍니다.
마지막으로 중복값이기 때문에 1보다 큰 경우만 사용하기 위해 filter 함수를 사용해 주고,
!!!value.order를 기준으로!! 오름차순으로 정렬해 주고, value.count를 배열로 묶어 주면 원하는 값을 도출할 수 있습니다!!
Set을 이용한 로직
func solution_Version_Set(_ array: [Int]) -> [Int] {
var set: Set<Int> = []
var orderAndCountArray = Array(repeating: (order: 0, count: 0), count: 101)
func sameValueCount(_ array: [Int]) {
var order = 1
for i in 0..<array.count {
let number = array[i]
if let temp = set.update(with: number) {
let (tempOrder, tempCount) = orderAndCountArray[temp]
orderAndCountArray[temp] = (order: tempOrder, count: tempCount+1)
continue
}
orderAndCountArray[number] = (order: order, count: 1)
order += 1
}
}
sameValueCount(array)
let resultArray = orderAndCountArray.filter { $0.count > 1 }.sorted(by: { $0.order < $1.order }).map{ $0.count }
return resultArray.isEmpty ? [-1] : resultArray
}
print(solution_Version_Set([1, 2, 3, 3, 3, 3, 4, 4])) // [4, 2]
print(solution_Version_Set([3, 2, 4, 4, 2, 5, 2, 5, 5])) // [3, 2, 3]
print(solution_Version_Set([3, 5, 7, 9, 1])) // [-1]
Set을 이용해서도 비슷한 로직으로 구현할 수 있습니다.
개인적으로 저는 dictionary 구현 방식이 더 좋은 것 같네요!
'Swift' 카테고리의 다른 글
[Swift] Dictionary에서 value를 이용해 key 구하기 (0) | 2023.05.18 |
---|---|
[Swift] String.index에 접근해 보자 (2) (Feat: prefix, suffix) (0) | 2023.03.04 |
[Swift] String index에 접근해 보자 (Feat: Substring) (0) | 2022.09.14 |
[Swift] 문자열의 문자 재정렬 (reversed, sort, sorted) (0) | 2022.09.06 |