[iOS] Higher-Order Functions

Eugenie·2022년 8월 17일
0

Higher-Order Functions

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

Swift 의 함수(클로저) 는 일급 시민이기 때문에
함수의 전달인자로 전달할 수 있으며, 함수의 결과값으로 반환할 수 있다.

가장 잘 알려진 고차함수로는
map, compactMap, flatMap, reduce, filter 등이 있다.

map

map 함수는 배열의 요소를 변환하는 고차함수이다.

// example "map"
let numbers = [10, 30, 91, 50, 100, 39, 74]

var formattedNumbers: [Stirng] = []

for number in numbers {
	let formattedNumber = "\(number)$"
   	formattedNumbers.append(formattednumber)
}

let mappedNumbers = number.map{ "\($0)$" }

위의 예시를 보면

변수 formattedNumbersmappedNumbers 의 값은
["10$", "30$", "91$", "50$", "100$", "39$", "74$"] 으로 같다.

formattedNumbersfor 문을 통해
numbers 의 요소를 순회하면서 "\(number)$" 의 형태로 바꿔준 뒤
append 메소드를 사용하여 값을 넣어주었다.

반면 mappedNumbers 는 고차함수 map 을 활용하여
좀 더 간단하게 처리를 할 수 있었다.

filter

filter 함수는 요소가 결과에 포함되어야하는지를 나타내는
Bool 값을 리턴하는 함수가 내장되어있다.

// example "filter"
let evenNumbers = numbers.filter { $0 % 2 == 0 }

위의 예시는 고차함수 filter 를 활용하여
number 에 있는 짝수만을 상수 evenNumbers 에 넣도록 하였다.

filter 를 사용하지 않았다면
위의 map 의 예시와 같이 배열을 순회하면서
짝수인지 확인하는 조건을 추가하여
짝수만을 담을 변수에 append 해주었을 것이다.

reduce

reduce 함수는 배열을 단일값으로 줄일 수 있다.

let total = numbers.reduce(0) { $0 + $1 }

위의 예시는 상수 totalnumbers 의 요소들의 합을 넣도록 하고 있다.

고차함수 reduce 는 두 개의 매개변수를 요구하는데
시작값과 합계 함수가 이에 해당한다.

예시에서 reduce 뒤에 (0) 이 바로 시작값이 되고
{ $0 + $1 } 이 합계 함수가 된다.

예시를 다음과 같이 다르게 표현할 수도 있다.

let total = numbers.reduce(0, +)

compactMap

compactMap 함수는 배열안에 nil 값이 있을 때 유용하다.

다음 예시는 배열 안에 있는 문자열들을 대문자로 바꾸고 있다.

// example no "compactMap"
let words: [String?] = ["room", "home", nil, nil, "green"]

let uppercasedWords = words.map({ word -> String? in
	if let word = word {
    	return word.uppercased()
    } else {
    	return nil
    }
})

앞서 배웠던 map 을 활용한다면 아래의 표현도 가능하다.

// example no "compactMap"
let  uppercasedWords = words.map{ $0 != nil ? $0.uppercased() : nil }

위의 두 예시는 모두 compactMap 을 사용하지 않았기때문에
nil 에 대한 처리를 따로 해주었다.

// example "compactMap"
let uppercasedWords = words.compactMap { $0?.uppercased() }

이번에는 compactMap 을 적용해보았다.

compactMap 은 배열의 모든 요소를 순회하면서 nil 이 아닌 값에
원하는 연산을 할 수 있다.

flatMap

flatMap 함수는 어떤 배열이든 1차원 배열로 변환한다.

// example no "flatMap"
let words: [[String]] = [["room", "home"], ["train", "green"]]
var singleArray: [String] = [String]()

for individualArray in words {
	for word in individualArray {
    	singleArray.append(word)
    }
}

위의 예시는 words 라는 2차원 배열을 1차원 배열로 변환하고 있다.
이중 for 문으로 배열을 순회하면서 변수 singleArray 에 요소를 넣어주고 있다.

flatMap 을 활용하면 좀 더 간단하게 표현할 수 있다.

let singleArray = words.flatMap { $0 }

📚 Reference
Higher-Order Functions in Swift
Swift Functional Programming - Second Edition Dr. Fatih Nayebi
yagom's Swift Basic

profile
🌱 iOS developer

0개의 댓글