주제: Swift 표준 라이브러리에서 제공하는 고차함수 map, filter, reduce
(참고: yagom's blog, 개발하는 훈이님 블로그 )
📌 고차함수란?
고차함수(Higher-order function)는
다른 함수를 *전달인자로 받거나, 함수실행의 결과를 함수로 반환하는 함수를 뜻한다.
map, filter, reduce 함수는 Swift 표준 라이브러리의 컨테이너 타입(Array, Set, Dictionary 등)에 구현되어 있다.
(+) 추가: reduce함수는 String 타입에도 사용 가능하다. 본문 끝 예제 1 참고
💁🏻♀️참고 :전달인자란? (링크) 매개변수(parameter) vs. 전달인자(arguement) |
|
- 매개변수 : 함수의 정의부분에 나열되어 있는 변수들. ex. f(x) = x*x 와 같은 함수 정의 부분에서 변수 'x' | - 전달인자 : 함수를 호출할 때 전달되는 실제 값. ex. f(2)와 같은 함수 호출 부분에서 값 '2' |
📌 map 함수의 기능과 문법
기능 : map은 컬렉션 내부의 데이터를 가공하여 새로운 컬렉션을 생성한다.
방식 : 클로저 1개를 인자로 받는다.
클로저는 컨테이너 내부에 들어있는 요소들의 값을 어떻게 바꿀 것인지 결정한다.
* apple 공식 문서 : (링크)
💙 map_방법 1
코드 : numbers.map( { (매개변수명: 데이터 타입 ) -> 반환할 데이터 타입 in return 식 })
예제 1) numbers의 각 요소를 2배하여 새로운 배열(doubleNumbers) 반환
doubleNumbers = numbers.map({ (number: Int) -> Int in
return number * 2
})
print(doubledNumbers) // [0, 2, 4, 6, 8]
예제 2) numbers의 각 요소를 문자열로 변환하여 새로운 배열(strings) 반환
strings = numbers.map({ (number: Int) -> String in
return "\(number)"
})
print(strings) // ["0", "1", "2", "3", "4"]
💙 map_방법 2
>> 매개변수, 반환 타입, 반환 키워드(return) 생략, 후행 클로저
예제 1) numbers의 각 요소를 2배하여 새로운 배열(doubleNumbers) 반환
코드 : numbers.map { $0 * 2 }
doubledNumbers = numbers.map { $0 * 2 }
print(doubledNumbers) // [0, 2, 4, 6, 8]
📌 filter 함수의 기능과 문법
기능 : 컨테이너 내부의 값을 걸러서 새로운 컨테이너로 추출한다.
방식 : 클로저 1개를 인자로 받는다.
이 클로저 내부에는 어떤 데이터를 새로운 컨테이너로 추출시킬지 그 조건을 정의한다.
💙 filter_방법 1
코드 : numbers.filter { (매개변수명: 반환 타입 ) -> Bool in return 논리식
예제 : numbers의 요소 중 짝수를 걸러내어 새로운 배열로 반환
let evenNumbers: [Int] = numbers.filter { (number: Int) -> Bool in
return number % 2 == 0
}
print(evenNumbers) // [0, 2, 4]
💙 filter_방법 2
>> 매개변수, 반환 타입, 반환 키워드(return) 생략, 후행 클로저
코드 : numbers.filter { $0 > 2 }
예제 : numbers의 요소 중 홀수를 걸러내어 새로운 배열로 반환
let oddNumbers: [Int] = numbers.filter {
$0 % 2 != 0
}
print(oddNumbers) // [1, 3]
📌 reduce 함수의 기능과 문법
기능 : 컨테이너 내부의 콘텐츠를 하나로 통합한다. -- 더하거나 빼거나 곱하거나...
방식 : 2개의 인자를 받는다.
- 첫번째 인자 : 통합할 데이터의 초기 값
- 두번째 인자 : 어떻게 값을 통합할 것인지를 정의하는 클로저
이때 사용되는 두 파라미터 중 첫번째는 바로 이전 값에 대한 통합된 데이터를 의미하고,
두번째는 이번에 새로 통합할 데이터를 의미한다.
=> let numberSum = numbers.reduce(0, { $0 + $1 })
구현 방식은 다양한데, 예제와 함께 다뤄보겠다.
문제 : 정수를 담고 있는 배열 arr의 평균값을 return하는 함수, solution을 완성해보세요.
💁🏻♀️ (프로그래머스 링크)
💙 reduce_방법 1
someNumbers.reduce(초깃값, { (first: Int, second: Int) -> Int in return 식 })
func solution(_ arr:[Int]) -> Double {
// sum 변수에 reduce를 사용하여 arr 합 담기
let sum = arr.reduce(0, {(result: Int, currentItem: Int) -> Int in
return result + currentItem })
// sum을 원소 개수로 나누기
return Double(sum) / Double(arr.count)
}
💙 reduce_방법 2
(1) someNumbers.reduce(초깃값) { $0 연산자 $1 }
(2) someNumbers.reduce(초깃값, { $0 연산자 $1 })
// (1)
func solution(_ arr:[Int]) -> Double {
return Double(arr.reduce(0) {$0 + $1}) / Double(arr.count)
}
// (2)
func solution2(_ arr:[Int]) -> Double {
return Double(arr.reduce(0, {$0 + $1})) / Double(arr.count)
}
💙 reduce_방법 3
someNumbers.reduce(초깃값, 연산자)
func solution(_ arr:[Int]) -> Double {
return Double(arr.reduce(0, +)) / Double(arr.count)
}
💚 (참고) for...in 구문으로 대체
참고로, for...in 구문으로도 풀 수 있는데, 코드가 더 길어진다.
func solution(_ arr:[Int]) -> Double {
var sum = 0
for i in arr {
sum += i
}
var avg = Double(sum) / Double(arr.count)
return avg
}
📌 예제
1) reduce 사용 예제
문제: 자연수 N의 각 자릿수 더하기
자세한 내용 > 코드카타 입문 #13. 자릿수 더하기
import Foundation
func solution(_ n:Int) -> Int
{
return String(n).reduce(0, {$0+Int(String($1))!});
}
2) filter, reduce 동시 사용 예제
문제: 정수 n의 약수를 모두 더한 값을 return
자세한 내용 > 코드카타 입문 #14. 약수의 합
func solution(_ n:Int) -> Int {
guard n > 0 else {
return 0
}
return Array(1...n).filter{n % $0 == 0}.reduce(0, +)
}
3) map 사용 예제
문제: x부터 시작해 x씩 증가하는 숫자를 n개 지니는 리스트 반환
자세한 내용 > 코드카타 입문 #16. x만큼 간격이 있는 n개의 숫자
func solution(_ x:Int, _ n:Int) -> [Int64] {
return Array(1...n).map { Int64($0 * x) }
}
'Swift > 문법' 카테고리의 다른 글
[Swift] 고차함수 - map 시리즈(map, flatMap, compactMap) (0) | 2024.02.14 |
---|---|
[Swift] Character를 Int로 변환하기 - .wholeNumberValue, hexDigitValue, Int(String(문자)) (0) | 2024.02.07 |
[Swift] if...else 구문 대신 사용 가능한 Ternary Conditional Operator (삼항 연산자) (0) | 2024.02.07 |
[Swift] 함수 - 매개변수 앞 언더바('_') (외부 매개변수, 내부 매개변수) (2) | 2024.02.07 |
앱개발 용어 정리(3) - 구조체와 클래스, 메서드 (0) | 2024.02.07 |