개인적으로 한번 헷갈리기 시작해 영원히 헷갈리는 문법이 몇 가지 있는데, 그 중 첫번째 손님으로 고차함수 map과 reduce 모심
✅ 각 요소를 변환하는 Map
class MapExamples {
func basicMapExamples() {
print("=== MAP 기본 예시 ===")
// 예시 1: 숫자를 2배로
let numbers = [1, 2, 3, 4, 5]
// Before: for문 사용
var doubled: [Int] = []
for number in numbers {
doubled.append(number * 2)
}
print("for문 결과: \(doubled)")
// After: map 사용
let doubledWithMap = numbers.map { $0 * 2 }
print("map 결과: \(doubledWithMap)")
print()
// 예시 2: 숫자를 문자열로
let numberStrings = numbers.map { "숫자: \($0)" }
print("문자열 변환: \(numberStrings)")
// 예시 3: 타입 변환
let stringNumbers = ["1", "2", "3", "4", "5"]
let integers = stringNumbers.map { Int($0)! }
print("타입 변환: \(integers)")
}
// 🎯 언제 map을 사용할까?
func whenToUseMap() {
print("=== MAP 사용 시점 ===")
// ✅ 사용해야 할 때
print("✅ 이런 상황에서 map 사용:")
// 1. 각 요소를 다른 형태로 변환
let ages = [25, 30, 35, 40]
let ageDescriptions = ages.map { "\($0)세" }
print("나이 설명: \(ageDescriptions)")
// 2. 객체의 특정 프로퍼티만 추출
struct Person {
let name: String
let age: Int
}
let people = [
Person(name: "김철수", age: 25),
Person(name: "이영희", age: 30),
Person(name: "박민수", age: 35)
]
let names = people.map { $0.name }
print("이름들: \(names)")
// 3. 계산 결과 배열 만들기
let prices = [1000, 2000, 3000]
let taxIncluded = prices.map { Double($0) * 1.1 } // 세금 포함
print("세금 포함 가격: \(taxIncluded)")
print()
// ❌ 사용하지 말아야 할 때
print("❌ 이런 상황에서는 map 사용 안함:")
// 1. 하나의 값으로 합치고 싶을 때 (reduce 사용)
let sum = ages.reduce(0, +) // map 아님!
print("나이 합계: \(sum)")
// 2. 조건에 맞는 것만 걸러내고 싶을 때 (filter 사용)
let adults = people.filter { $0.age >= 30 } // map 아님!
print("성인: \(adults.map { $0.name })")
}
}
✅ 여러 개를 하나로 합치는 Reduce
class ReduceExamples {
func basicReduceExamples() {
print("=== REDUCE 기본 예시 ===")
let numbers = [1, 2, 3, 4, 5]
// 예시 1: 합계 구하기
// Before: for문 사용
var sum = 0 // 초기값
for number in numbers {
sum = sum + number // 누적
}
print("for문 합계: \(sum)")
// After: reduce 사용
let sumWithReduce = numbers.reduce(0) { result, number in
return result + number
}
// 또는 더 간단히
let sumSimple = numbers.reduce(0, +)
print("reduce 합계: \(sumWithReduce)")
print("reduce 간단: \(sumSimple)")
print()
// 예시 2: 곱하기
let product = numbers.reduce(1, *) // 초기값 1!
print("곱셈 결과: \(product)")
// 예시 3: 문자열 합치기
let words = ["안녕", "하세요", "반갑습니다"]
let sentence = words.reduce("") { result, word in
result + word + " "
}
print("문장: '\(sentence)'")
}
// 🤔 reduce의 초기값(0) 이해하기
func understandInitialValue() {
print("=== REDUCE 초기값 이해하기 ===")
let numbers = [10, 20, 30]
// 초기값이 0일 때
let sum0 = numbers.reduce(0) { result, number in
print(" \(result) + \(number) = \(result + number)")
return result + number
}
print("초기값 0으로 합계: \(sum0)")
print()
// 초기값이 100일 때
let sum100 = numbers.reduce(100) { result, number in
print(" \(result) + \(number) = \(result + number)")
return result + number
}
print("초기값 100으로 합계: \(sum100)")
print()
// 초기값이 1일 때 (곱셈)
let product = numbers.reduce(1) { result, number in
print(" \(result) × \(number) = \(result * number)")
return result * number
}
print("초기값 1로 곱셈: \(product)")
print()
// 초기값이 빈 문자열일 때
let numberStrings = ["1", "2", "3"]
let combined = numberStrings.reduce("시작:") { result, str in
print(" '\(result)' + '\(str)' = '\(result + str)'")
return result + str
}
print("문자열 합치기: '\(combined)'")
}
// 🎯 언제 reduce를 사용할까?
func whenToUseReduce() {
print("=== REDUCE 사용 시점 ===")
// ✅ 사용해야 할 때
print("✅ 이런 상황에서 reduce 사용:")
let scores = [85, 92, 78, 96, 88]
// 1. 합계, 평균
let total = scores.reduce(0, +)
let average = Double(total) / Double(scores.count)
print("총점: \(total), 평균: \(average)")
// 2. 최대값, 최소값 찾기
let maxScore = scores.reduce(scores[0]) { max($0, $1) }
let minScore = scores.reduce(scores[0]) { min($0, $1) }
print("최고점: \(maxScore), 최저점: \(minScore)")
// 3. 개수 세기 (filter + count 대신)
let passCount = scores.reduce(0) { count, score in
count + (score >= 80 ? 1 : 0)
}
print("80점 이상: \(passCount)명")
// 4. 복잡한 계산
let weightedAverage = scores.reduce((0, 0)) { result, score in
let (totalScore, count) = result
return (totalScore + score, count + 1)
}
print("가중평균 계산용 데이터: \(weightedAverage)")
print()
// ❌ 사용하지 말아야 할 때
print("❌ 이런 상황에서는 reduce 사용 안함:")
// 1. 각 요소를 변환하고 싶을 때 (map 사용)
let doubled = scores.map { $0 * 2 } // reduce 아님!
print("2배: \(doubled)")
// 2. 조건에 맞는 것만 필터링할 때 (filter 사용)
let highScores = scores.filter { $0 >= 90 } // reduce 아님!
print("90점 이상: \(highScores)")
}
}
✅ 실제 사용 예시
class PracticalPatterns {
func commonPatterns() {
print("=== 자주 사용하는 패턴들 ===")
let numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
// 패턴 1: map + filter 조합
let evenDoubled = numbers
.filter { $0 % 2 == 0 } // 짝수만
.map { $0 * 2 } // 2배로
print("짝수를 2배: \(evenDoubled)")
// 패턴 2: map + reduce 조합
let squareSum = numbers
.map { $0 * $0 } // 제곱
.reduce(0, +) // 합계
print("제곱의 합: \(squareSum)")
// 패턴 3: filter + reduce 조합
let evenSum = numbers
.filter { $0 % 2 == 0 } // 짝수만
.reduce(0, +) // 합계
print("짝수의 합: \(evenSum)")
// 패턴 4: 체이닝
let result = numbers
.filter { $0 > 5 } // 5보다 큰 수
.map { $0 * 3 } // 3배
.reduce(0, +) // 합계
print("5보다 큰 수를 3배해서 합계: \(result)")
}
}
'Swift' 카테고리의 다른 글
[Swift] Any와 AnyObject (0) | 2025.06.12 |
---|---|
[Swift] 캡처리스트와 순환참조 (1) | 2025.06.05 |
[WWDC] ARC in Swift (0) | 2025.05.30 |
Struct 접근제어와 Memberwise Initializers (0) | 2025.05.29 |
[Swift]switch문 대신 if, guard 사용하기 (0) | 2025.05.28 |