[iOS] 고차 함수와 함수형 프로그래밍

Zoe·2023년 12월 12일
0

iOS

목록 보기
30/39

🌟 고차 함수는
"다른 함수를 전달인자로 받거나 함수실행의 결과를 함수로 반환하는 함수"이다.

Swift에서 함수는 1급 객체이기 때문에 함수를 전달 인자로 보내거나, 변수/상수로 저장 혹은 전달하거나, 함수의 반환값으로 쓸 수 있다.
이 때, 다른 함수를 전달인자로 받거나, 함수실행의 결과를 함수로 반환하는 함수가 고차함수의 정의인 것이다.

Swift에서 특히 자주 사용하는 고차함수로 map, filter, reduce, compactMap, flatMap이 있다.

✅ map

map 함수는 컨테이너 내부의 기존 데이터를 변형하여 새로운 컨테이너를 생성한다.
여기서 Array, Set, Dictionary와 같은 자료구조들이 일종의 컨테이너라고 할 수 있다.
시간복잡도는 O(n)이며, n은 컨테이너의 길이이다.

let numbers: [Int] = [0, 1, 2, 3, 4]
var doubledNumbers: [Int]
doubledNumbers = numbers.map { $0 * 2 }
print(doubledNumbers) // [0, 2, 4, 6, 8]

✅ filter

filter 함수는 컨테이너 내부의 값을 걸러서 새로운 컨테이너로 추출한다. 시간복잡도는 O(n)이며, n은 컨테이너의 길이이다.

let numbers: [Int] = [0, 1, 2, 3, 4]
let oddNumbers: [Int] = numbers.filter {
    $0 % 2 != 0
}
print(oddNumbers) // [1, 3]

✅ reduce

reduce함수는 컨테이너 내부의 콘텐츠를 하나로 통합한다. 시간복잡도는 O(n)이며, n은 컨테이너의 길이이다.

let someNumbers: [Int] = [2, 8, 15]
let sumFromThree = someNumbers.reduce(3) { $0 + $1 }
print(sumFromThree) // 28

✅ flatMap

flatMap함수는 2차원 배열을 1차원 배열로 flat하게 만들어주고 싶을 때 사용한다. 시간복잡도는 O(n+m)이며, n은 배열의 길이 m은 결과값의 길이이다.

let scores = [[5,2,7], [4,8], [9,1,3]]

let allScores = scores.flatMap { $0 } // [5, 2, 7, 4, 8, 9, 1, 3]
let passMarks = scores.flatMap { $0.filter { $0 > 5} } // [7, 8, 9]

✅ compactMap

compactMap함수는 1차원 배열에서 nil값을 제거하고, 옵셔널 바인딩을 해준다. 시간복잡도는 O(n+m), n은 배열의 길이 m은 결과값의 길이이다.

let array = [1,2,nil,10,123,nil,nil]
let cmapTest = array.compactMap{ $0 } //[1, 2, 10, 123]

Swift 의 고차함수에서 가장 많이 쓰이는 함수들을 알아봤다.

그리고 함수형 프로그래밍 개념 중 MaybeEither라는 개념이 있다.
상황에 따라 두 가지 타입의 결과값을 가지는 경우 주로 사용한다.

✅ Maybe

Maybe는 값이 있을 수도 있고, 없을 수도 있다는 개념이다. Swift에서는 Optional이라는 이름으로 이 개념이 구현되었다.

간단하게 예제를 보자면

var maybeString: String? = "maybe"
print(maybeString)  // 출력: Optional("maybe")

maybeString = nil
print(maybeString)  // 출력: nil

✅ Either

Either는 두 가지 타입을 가질 수 있는 경우에 사용한다. 주로 성공과 실패, 또는 두 가지 다른 유형의 반환값을 처리할 때 사용된다.

swift로 success or failure에 대해 구현하자면 아래와 같다.

enum Either<T, U> {
    case left(T)
    case right(U)
}

let success = Either<Int, String>.left(200)
let failure = Either<Int, String>.right("Error")

switch success {
case .left(let value):
    print("Success with value \(value)")
case .right(let error):
    print("Failure with error \(error)")
}

이 Either의 개념을 가지고 나타난 것이 바로 swift의 Result이다.
Result란 Either에서 성공/Error로 제한을 걸어 사용하는 자료구조인 것이다.

profile
iOS 개발자😺

0개의 댓글

관련 채용 정보