TIL 11일 차 - Swift 필수 문법 문제 2번 풀이


문제 2-1.
아래 for-in 문을 map을 사용하는 코드로 변환해 주세요.
let numbers = [1, 2, 3, 4, 5]
var result = [String]()
for number in numbers {
result.append(number)
}
고차함수를 써본 적이 거의 없고 개념 정리가 안되어있어서 챕터 5에 있던 고차함수강의를 우선수강하고 개념 정리 후 문제를 풀었다.
let numbers = [1, 2, 3, 4, 5]
var result = [String]()
result = numbers.map { String($0) }
print(result)
map 이란?
- 배열의 각 요소를 변환하여 새로운 배열을 생성함
- 각 요소를 변형하는 작업을 반복하며, 변형된 값을 새로운 배열로 반환함
즉 map함수가 numbers 배열을 하나씩 돌면서 String으로 타입을 변형시키고 result에 append 해준 것이다.
문제 2-2.
- 주어진 입력값을 고차함수를 체이닝 하여 주어진 출력값이 나오도록 구현해 주세요.
- 입력: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] - 타입: Array <Int>
- 출력: [”2”, “4”, “6”, “8”, “10”] - 타입: Array <String>
- 힌트
- map과 filter를 이용해 볼 수 있을 것 같습니다.
내가 처음 풀었던 풀이
let numbers2 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
var result2 = numbers2.filter { $0 % 2 == 0}
var result3 = result2.map { String($0) }
이 풀이의 문제점을 마스터 1팀 예슬 님이 pr에 리뷰를 해주셨는데 문제에서 제시한 체이닝 방식이 쓰이지 않았다는 것이다.
스위프트에서 체이닝 방식이란
- 앞에서 나온 결과를 변수에 담지 않고 바로 다음 함수로 이어서 처리하는 방식이다.
let numbers2 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
let result2 = numbers2 // 후에 바뀔일이 없는 배열이므로 var 대신 let으로 선언하는것이 좋다.
.filter { $0 % 2 == 0}
.map { String($0) }
이런 식으로 연결해서 쓸 수 있는데
중요한 포인트는 filter의 결과가 배열이기 때문에 그 배열에 바로 map함수를 호출하여 사용할 수 있다는 것이다.
그리고 이번엔 마스터1팀 예린 님이 리뷰해 주셨던 부분인데
result2 배열은 후에 더 이상 바뀔 일이 없으므로 let으로 선언하는 것이 좋다.
var대신 let으로 선언하면 대체 뭐가 좋냐.!!
(1) 이 값은 안 바뀐다는 의도를 명확히 전달함
(2) 스위프트의 철학 중 하나가 변경이 필요할 때만 var를 쓰고 나머지는 let을 써주는 게 좋음
(3) 값이 바뀌지 않아야 하는 상수를 후에 실수로 고치게 되는 것을 컴파일 단계에서 차단해 줌
문제 2-3.
- 이제 고차함수를 직접 만들어 봅니다.
- 함수명: myMap
- 파라미터는 2개입니다.
- 배열: [Int]
- 변환 클로저: (Int) → String
- 반환 값은 1개입니다.
- [String]
- myMap 함수 구현 내부에서 map, filter, reduce 등 고차함수를 직접 사용하지 않아야 합니다.
- 완성된 myMap 호출 예시
- let result = myMap([1, 2, 3, 4, 5]) { String($0) } print(result) // ["1", "2", "3", "4", "5"]
내가 처음으로 풀었던 막장 풀이 대공개
func myMap (a: [Int], operation: (Int) -> String) -> [String] {
var result = [String]()
for i in a {
result.append(String(i))
}
// 이렇게 엉망진창으로 풀어놓고도 잘 출력되길래 일단 뿌듯해함

호출되었던 클로저가 얼마나 서운했을까.. 불러놓고 쓰지도 않고
일단 이 문제부터 깊게 파고 들어보자 myMap함수를 구현하는데 왜 클로저를 파라미터로 쓰라고 한 걸까?
만약 파라미터로 클로저를 사용하지 않으면 이런 식으로 구현하게 된다.
func myMap(_ array: [Int]) -> [String] {
// 변환방식이 하나로 고정되어 항상 문자열로만 변환이 가능하고 재사용은 불가함
}
하지만.. 클로저를 사용한다면?
변환 방식만 밖에서 주입해 주어 어떻게 바꿀지는 함수 밖에서 결정하게 해 재사용성이 뛰어난다.
따라서 최종 리펙토링 한 코드:
func myMap (a: [Int], operation: (Int) -> String) -> [String] {
var result = [String]()
for i in a {
result.append(operation(i)) // 파라미터로 받은 클로저 이용해서 변환
}
return result
}
let result4 = myMap(a: [1, 2, 3, 4, 5]) {
String($0) // Int를 받아 String을 돌려줘야하므로
}
print(result4) // ["1", "2", "3", "4", "5"] 출력
'iOS > Swift ' 카테고리의 다른 글
| [iOS-Swift] 스위프트 필수 문법 문제 4번 풀이 (0) | 2026.01.10 |
|---|---|
| [iOS- Swift] 스위프트 필수 문법 문제 3번 풀이 (0) | 2026.01.09 |
| [iOS-Swift] 스위프트 필수 문법 문제 1번 풀이 (0) | 2026.01.09 |
| [iOS-Swift] 타입캐스팅 (0) | 2026.01.09 |
| [iOS-Swift] 접근 제어자 (0) | 2026.01.08 |