
TIL 19일 차 - 고차함수 Map, compactMap, flatMap 활용하기
<Map>
1. 모든 원소에 동일한 연산 적용하기
// 모든 숫자 2배로 만들기
let nums = [1, 2, 3, 4]
let doubled = nums.map { $0 * 2 } // 각 원소에 같은 연산을 적용
// [2, 4, 6, 8] 출력
2. 타입 변환 (ex. Int -> String)
let nums = [1, 2, 3]
let Strings = num.map { String($0) }
// ["1", "2", "3"] 출력
3. 문자열 배열 가공 (전부 대문자로 바꾸기)
let names = ["iOS", "Swift", "Apple"]
let upper = names.map { $0.uppercased() }
// ["IOS", "SWIFT", "APPLE"] 출력
4. 모델 -> 필요한 값만 추출
// 객체 배열 -> 특정 프로퍼티 배열
struct User {
let name: String
let age: Int
}
let users = [
User(name: "A", age: 20)
User(name: "B", age: 25)
]
let names = users.map { $0.name }
// ["A", "B"]
5. Optional과 map
let number: Int? = 3
let result = number.map { $0 * 2 }
// Optional(6) // 옵셔널에서도 map 가능
5. Range를 Array로 변경
// 빈 배열, 반복문 필요 없이 한줄로 생성 가능
let arr = (0...9).map { $0 }
// 0부터 9까지 들어있는 배열
// arr == [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
// 사실은 let arr = Array(0...9)로도 쓸 수 있음
<compactMap>
compactMap은 Map과 다른 점이 무엇일까?
Map: 원소의 개수가 변하지 않음, nil도 결과에 포함시킴
compactMap: nil을 제거하고 값만 모음
1. nil값을 제거
// Map에서의 Optional
let strings = ["1", "2", "three", "4"]
let mapped = string.map { Int($0) }
// [Int?, Int?, Int?, Int?]
// [1, 2, nil, 4]
// compactMap에서의 optional
// 위와 같은 예제일때
let compacted = string.compactMap { Int($0) }
// [1, 2, 4] // nil값 제거 됨
따라서 map을 써야할때:
- 결과 개수가 무조건 같아야 할 때
- nil도 의미 있는 값일 때
- 단순 변형
compactMap을 써야할 때:
- 변환 중 실패할 수 있을때 (앱 폭발 방지)
- nil을 버리고 싶을때
- Optional 제거가 목적일 때
2. 문자열 -> 숫자 변환 (실무/코테에서 자주 쓰는 패턴)
let inputs = ["10", "20", "x", "30"]
let numbers = input.compactMap { Int($0) }
// [10, 20, 30]
3. guard + compactMap으로 숫자 입력 검증하기
let inputs = ["1", "2", "x"]
let nums = inputs.compactMap(Int.init)
guard nums.count == inputs.count else {
print("숫자가 아닌 입력이 있습니다.")
return
}
4. 입력한 수를 각각 한개씩 쪼개 배열로 반환하기
// MARK: - 입력한 수를 숫자 각 한개씩으로 배열로 쪼개는 함수
private func splitNum(_ num: Int) -> [Int] {
let result = String(num).compactMap{ Int(String($0))}
return result
}
먼저 입력한 세자리수 num이 String(num)으로 들어와 예) 907 -> "907" 문자열로 변환된다.
그런 다음은 "907".compactMap{ Int(String($0)) }인데 문자열은 character단위로 ["9", "0", "7"]로 순회하므로
String -> Int순으로 만들어주고 숫자면 Int? 값으로 반환되고 숫자가 아니면 nil값이 반환된다(compactMap에선 삭제됨)
이 코드의 장점은 자리수가 자동으로 처리되어 유동적으로 사용할 수 있다.
<flatMap>
flatMap은 옵셔널 안에 옵셔널이 들어있는 상태(??)를 한 겹(?)으로 펴는 기능도 한다.
guard let inputNumber = readLine().flatMap(Int.init)
1) 먼저 위의 코드의 readLine()은 string? 값을 return 한다.
2) 그다음 Int.init은 입력받은 문자열을 숫자로 변환하려 하므로 Int? 값을 반환한다.
3) 만약 flatMap이 아닌 map을 사용한다면 Int?? 를 반환하게 된다.
4) 대신 flatMap을 사용하면 Int? 값을 return 해주어 구조를 단순하게 정리해 주게 된다.
5) guard let inputNumber =.. 단계에서 옵셔널을 해제한다.
'iOS > Swift ' 카테고리의 다른 글
| [iOS-Swift] 심화 문법 - 숫자 야구 게임 최종 리팩토링 (1) | 2026.01.21 |
|---|---|
| [Swift 알고리즘] 의상 갈아입기 알고리즘 문제 풀이 (1) | 2026.01.21 |
| [iOS-Swift] 심화 문법 문제 - 숫자 야구 게임 (0) | 2026.01.18 |
| [iOS-Swift] 스위프트에서 문자열 뒤집기 + reduce (0) | 2026.01.16 |
| [iOS-Swift] 기초 문법 개인 과제 최최최종_리팩토링.swift (0) | 2026.01.14 |