[iOS-Swift] 문법 기초주차 과제 최종 리펙토링

TIL 13일 차 - Swift 문법 과제 최종 리펙토링

과제 풀이 Github 링크

 

<필수 과제>

1번 문제.

내가 푼 1번 문제 풀이

🍏 클로저 본문이 한 줄이면 in return에서 return 생략 가능하다.

let sum: (Int, Int) -> String = { a, b in
    return "두 수의 합은 \(a + b) 입니다."
}
let sum: (Int, Int) -> String = { a, b in
    "두 수의 합은 \(a + b) 입니다."   // return을 생략하더라도 마지막 한 줄이 자동 반환
}

 

 

 

2번 문제.

내가 푼 2번 문제 풀이

🍏 .map { String($0) }는 각 요소를 받아서 String(요소)로 바꾸는 것이다.

그런데 String($0)은 String의 생성자를 부르는 것이므로 그 생성자 자체를 map에 바로 넘길 수 있다.

따라서 map(String.init)으로 써도 같은 결과가 출력된다.

let numbers = [1, 2, 3, 4, 5]

let resultA = numbers.map { String($0) }
let resultB = numbers.map(String.init)

print(resultA) // ["1", "2", "3", "4", "5"] 출력
print(resultB) // ["1", "2", "3", "4", "5"] 출력

 

 

🍏 또한 짝수값을 출력하기 위해 썼던. filter { $0 % 2 == 0 } 대신 { $0.isMultiple(of: 2) }를 활용하여도 같은 결과가 출력된다.

해당 구문은 $0에 해당하는 값이 2의 배수에 해당하는지를 Bool로 돌려주게 된다.

let numbers2 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

let resultA = numbers2.filter { $0 % 2 == 0}.map { String($0) }
let resultB = numbers2.filter { $0.isMultiple(of: 2) }.map(String.init)


print(resultA) // ["2", "4", "6", "8", "10"] 출력
print(resultB) // 같은 값 출력

 

 

 

3번 문제.

내가 푼 3번 문제 풀이

 

🍏 기존 풀이 방식인 for문과 if문을 이용해서 풀 수도 있지만

입력받은 array배열을. enumerated()를 이용해 배열을 '인덱스(offset) + 값(element)' 형태인 EnumeratedSequence라는 타입으로 만들어 문제를 보다 간결하게 풀어줄 수 있다.

func a(_ array: [Int]) -> [Int] {
    array.enumerated() // [(0, 1), (1, 2), (2, 3), (3, 4), (4, 5)]
        .filter { (idx, _) in // 튜플에서 인덱스만 보고 2의 배수인것만 남긴다
            idx.isMultiple(of: 2) // [(0, 1), (2, 3), (4, 5)]만 필터링 되어서 남음
        }
        .map { (_, value) in // 튜플에서 value값만 뽑아서 배열로 만듬
            value
        }
        // [1, 3, 5]
    // 위의 구문도 따지고 보면 한줄이라 return 생략함
}

print(a([1, 2, 3, 4, 5])) // [1, 3, 5] 출력

 

 

 

4번 문제.

내가 푼 4번 문제 풀이

🍏 나는 프로퍼티 옵서버에서 willSet을 이용하여 풀었는데 didSet을 이용해서도 풀이할 수 있다.

class Robot {
    var name: String {
        didSet {
            guard  oldValue != name else {
                return // 이전값과 동일하면 return으로 빠져나감
            }
            
            let log = """
                name 변경 알림
                변경 이전 값: \(oldValue)
                변경 이후 값: \(name)
                """
            
            print(log)
        }
    }
    init(name: String) {
        self.name = name
    }
}

var robot = Robot(name: "로봇1")
robot.name = "로봇2"    // name 변경 알림  변경 이전 값: 로봇1  변경 이후 값: 로봇2 출력

 

1) didSet

- 바뀐 다음에 실행함

- oldValue(이전 값)을 쓸 수 있음

- 이 시점의 name은 이미 새로 대입한 값임

 

2) willSet

- 바뀌기 전에 실행

- newValue(바뀔 값)을 쓸 수 있음

- 이 시점의 name은 아직 기존에 있던 값

 

 

🍏 for 반복문안에서 if문을 쭉 나열하면 앞에서 검사가 통과해도 뒤에 나열된 if문을 또 실행하게 되어 불필요한 실행이 반복된다.

// 반복문을 비효율적으로 작성한 코드 (수정 전 기존 코드)
for i in arrayIntroducible {
    if let robot = i as? Robot {
        print(robot.batteryCharge()) // 전원을 충전합니다. 출력
    }
    if let cat = i as? Cat {
        print(cat.grooming()) // 야옹 출력
    }
    if let dog = i as? Dog {
        print(dog.bark()) // 멍멍멍 출력
    }
}

// 3 x 3 = 총 9번 타입 검사를 반복함

 

 

🍏 else if 문을 이용해 비효율적인 반복을 줄이고 가독성을 높일 수 있다.

🍏 배열은 선언과 동시에 초기화를 해주면 더 간결하게 코드를 작성할 수 있다.

🍏 for in 문 대신 forEach(단, break 불가) 문을 이용할 수도 있다. (for-in 도 괜찮은 선택임)

let introducibles: [Introducible] = [robot, cat, dog] // 선언과 동시에 초기화
// 또한 앞으로 변경될 일 없는 배열 introducible는 var 대신 let으로 선언하는게 좋다.

arrayIntroducible.forEach { // for-in문을 forEach문으로 변경
    // i.batteryCharge() error: Value of type 'any Introducible' has no member 'batteryCharge'
    if let robot = $0 as? Robot { // 비효율적인 반복을 줄이고 가독성 향상을 위해 else if문으로 수정
        print(robot.batteryCharge())
    } else if let cat = $0 as? Cat {
        print(cat.grooming())
    } else if let dog = $0 as? Dog {
        print(dog.bark())
    }
}
// 3! = 총 6번 반복문을 실행하게 된다.

 

 

 

 

5번 문제.

내가 푼 5번 문제 풀이

 

🍏 throwing function을 정의할 때 if - else문을 사용할 수도 있지만 해당 조건에서는

guard문을 사용하면 조건 실패 시 바로 종료이기 때문에, if문을 사용했을 때 발생했던 else로 감싸서 발생한 들여 쓰기(중첩)이 사라져 가독성이 나아진다.

func predictDeliveryDay(for address: String, status: DeliveryStatus) throws -> String {
    
    guard !address.isEmpty else {
        throw DeliveryError.invalidAddress
    }
    // if else 대신 guard문 사용으로 가독성에 방해되는 들여쓰기 삭제 됨

 

 

 

경찰이 감금을 해요......ㅜㅜ

해. 보. 자(코딩 감금 쏘우방) 탈출 완료!