📌 인자 (Argument) 로 함수를 전달 받거나 실행 결과로 함수를 반환하는 함수
Swift 의 함수 (클로저) 는 일급 객체이므로 함수의 인자로 함수를 전달할 수 있고 실행 결과로 함수를 반환할 수 있습니다.
→ 즉, 고차함수 가 될 수 있습니다!!
일급 객체 (일급 시민)
"다른 객체들에 일반적으로 적용 가능한 연산을 모두 지원하는 객체를 가리킨다.
보통 함수에 인자로 넘기기, 수정하기, 변수에 대입하기 와 같은 연산을 지원할 때 일급 객체라고 한다."
고차 함수 는 컨테이너 타입 (Array, Set, Dictionary 등) 에 사용될 수 있고, 이들이 가진 각 요소에 대해 동작합니다.
Swift 표준 라이브러리에서는 map
, compactMap
, flatMap
, reduce
, filter
, contains
, sorted
, forEach
, removeAll
등을 제공하고 있으며, 일반적으로 후행 클로저 (Trailing Closure)
를 사용해서 표현합니다.
이 중에서 대표적인 map
, filter
, reduce
를 한번 다루어 보겠습니다!
변형
Returns an array containing the results of mapping the given closure over the sequence’s elements.
🔗 https://developer.apple.com/documentation/swift/sequence/3018373-map
map
은 전달된 클로저로 변형한 객체를 리턴합니다.
var floatNumbers : [Float] = [1.0, 2.0, 3.5, 4.0]
var integerNumbers : [Int] = floatNumbers.map { (num : Float) -> Int in
return Int(num)
}
print(integerNumbers) // [1, 2, 3, 4]
map
의 인자로 클로저가 전달되었고 클로저내에서 배열 각 요소에 대해 형변환이된 정수 배열을 반환합니다.
물론 클로저에서 자주 쓰는 타입 추론
, 리턴 구문 생략
, 파라미터 이름 생략
으로 더 간결하게 표현할 수 있습니다.
var integerNumbers : [Int] = floatNumbers.map { Int($0)! }
이걸 일반적으로 사용하는 for-loop
로 표현하면 조금 더 길고 복잡한 코드로 바뀌겠죠?
var floatNumbers : [Float] = [1.0, 2.0, 3.5, 4.0]
var integerNumbers : [Int] = []
for num in floatNumbers {
integerNumbers.append(Int(num))
}
조건을 만족하는 요소 추출
Returns an array containing, in order, the elements of the sequence that satisfy the given predicate.
🔗 https://developer.apple.com/documentation/swift/sequence/3018365-filter
filter
는 전달된 클로저의 조건을 만족하는 객체를 리턴합니다.
filter
로 전달되는 클로저의 리턴 타입은 Bool
이며 true
일 경우 해당 요소를 리턴합니다.
var numbers : [Int] = Array(1...10)
var evenNumbers : [Int] = numbers.filter { $0 % 2 == 0 }
print(evenNumbers) // [2, 4, 6, 8, 10]
누적, 결합
Returns the result of combining the elements of the sequence using the given closure.
🔗 https://developer.apple.com/documentation/swift/sequence/2907677-reduce
reduce
는 초기값과 클로저, 두 개의 파라미터를 전달받고
각 요소에 대하여 클로저 내에서 처리하여 초기값에 누적하여 결합할 수 있습니다.
var numbers : [Int] = [1, 2, 3, 4, 5]
var factorialNum : Int = numbers.reduce(1) { (result : Int, num : Int) -> Int
return result *= num
}
print(factorialNum) // 120
이처럼 배열을 순회하며 각 요소에 대해 누적하여 처리할 수 있습니다.
var factorialNum : Int = numbers.reduce(1) { $0 *= $1 }
Swift 에서는 연산자 역시 두 개의 파라미터를 받는 함수이므로 아래와 같이 표현할 수 있습니다.
var factorialNum : Int = numbers.reduce(1, *)
그래서 고차함수를 사용하면 뭐가 좋을까요?
O(n)
오늘은 깔끔하고 간결한 코딩을 할 수 있게 해주는 Swift 의 고차함수에 대해 알아봤습니다.
위의 대표적인 3가지 이외에도 Swift 에는 유용한 고차함수들이 많은데 한번 둘러보시길 추천합니다!
Apple Swift Documentation - Sequence
https://developer.apple.com/documentation/swift/sequence
틀린 정보 또는 궁금한 점이 있다면 댓글 부탁드립니다! 읽어주셔서 감사합니다‼️