[CharmingSwift] 1. if vs filter / forEach

miori·2022년 12월 5일
0

charmingSwift

목록 보기
2/2
post-thumbnail

단단한 기초, 매력적인 Swift를 Swift 답게 작성해보자

풀어볼 문제는 프로그래머스 최빈값구하기 이다.
자세한 문제와 예시는 여기 에서 확인 가능하다.

🔑 풀이 key

array 에서 최빈값을 구하는 게 핵심이었다.
따라서 딕셔너리를 이용해 배열의 원소를 key값으로, 그리고 몇번 나왔는지 카운트 한 값을 value로 지정을 해주어야 겠다고 생각했다.

📝 if를 사용한 풀이 코드

우선 딕셔너리를 만들고 배열을 순회하며, 딕셔너리에 값을 추가해주었다.

var countDictionary: [Int: Int] = [:]
for index in array {
    if countDictionary.keys.contains(index) {
        countDictionary[index]! += 1
    } else {
        countDictionary[index] = 1
    }
}

처음엔 다음과 같이 for문을 돌며, 딕셔너리의 키값에 넣어줄 키값이 포함된다면 value 를 1 더해주고, 아니라면 키값이 처음 나온것 이기에 value를 1로 지정해주었다.

let sortedDictionary = countDictionary.sorted(by: {$0.1 > $1.1})
return sortedDictionary.count > 1 && sortedDictionary[0].value == sortedDictionary[1].value ? -1 : sortedDictionary[0].key

그다음 가장 많이 나온 값을 꺼내야 했기 때문에 value 를 기준으로 내림차순으로 sort를 진행하였다.
그다음 삼항 연산자를 통해 가장 큰값이 두개 이상 있는 경우를 분기처리해주었다.
이때 딕셔너리가 한개인 경우는 오류가 발생하기 때문에 sortedDictionary.count > 1 조건을 추가하였다.

🍏 swift 다운 코드 작성해보기

forEach

forEach 를 사용하게 되면, 요소 갯수 만큼 클로저를 계속해서 실행한다.
따라서 단순하게 순회하여 딕셔너리를 생성하는 과정에서 forEach 를 사용하는게 더 합리적이라고 생각했다.
또한 break,continue를 사용하지 않기 때문에 forEach를 사용해도 무방할것이라고 판단했다.

filter

filter 를 사용하게 되면, if문을 대체할 수 있게 된다.
그리고 if문 보다 직관적이고 가독성이 뛰어나다.

해당 코드에서 max 값을 filter 하게 되면, 딕셔너리가 딱 한개로 보장 되기 때문에 위의 코드의 sortedDictionary.count > 1 처럼 조건을 추가해줄 필요가 없다.

정리

for-in vs. forEach

  • for-in은 연산자이고`for-each는 함수입니다.
  • for-in 은 break, continue를 사용하여 제어를 할 수 있다.
  • for-each는 closure 와 일급함수처럼 쓰이기 때문에, 함수를 forEach 구문안에 넣을 수 있다.

전체 코드

import Foundation

//MARK: 반복문 사용하여 딕셔너리에 추가후, 정렬하고 삼항연산자를 통해 푼 방법
// func solution(_ array:[Int]) -> Int {
//     var countDictionary: [Int: Int] = [:]
//     for index in array {
//         if countDictionary.keys.contains(index) {
//             countDictionary[index]! += 1
//         } else {
//             countDictionary[index] = 1
//         }
//     }
//     let sortedDictionary = countDictionary.sorted(by: {$0.1 > $1.1})
//     return sortedDictionary.count > 1 && sortedDictionary[0].value == sortedDictionary[1].value ? -1 : sortedDictionary[0].key
// }

//MARK: forEach 사용하여 딕셔너리 추가후, filter를 사용하여 max 키값-value값 추출 
func solution(_ array:[Int]) -> Int {
    var countDictionary: [Int: Int] = [:]
    array.forEach { 
        countDictionary[$0] = (countDictionary[$0] ?? 0) + 1
    }

    let maxDictionary = countDictionary.filter { $0.value == countDictionary.values.max() }
    return maxDictionary.count == 1 ? maxDictionary.first!.key : -1
}

// func solution(_ array: [Int]) -> Int {
//     let sorted = Dictionary(grouping: array) { $0 }.sorted { $0.value.count > $1.value.count }
//     return sorted.count > 1 && sorted[0].value.count == sorted[1].value.count ? -1 : sorted[0].key
// }
profile
iS를 공부하는 miori 입니다.

0개의 댓글