iOS/Swift

[Swift] 고차함수(High-order function) - map, filter, reduce

듀IT 2022. 1. 24. 23:06

고차함수


Swift는 함수형 언어이기 때문에, 어떤 함수를 객체로 취급하여 다른 함수의 인자로 전달할 수 있다. (https://dew-it.tistory.com/65)

 

[iOS] 함수형 언어 Swift - 일급 함수

Swift는 객체지향 언어이자 함수형 언어이다. 함수형 언어가 되기 위해서는 일급 함수의 조건을 만족해야 한다. Swift에서 Closure는 매우 중요한 개념인데, 이를 이해하기 위해서는 일급함수의 개념

dew-it.tistory.com

고차함수는 이러한 특성을 이용하는데,  다른 함수를 인자로 전달 받거나 함수의 실행 결과를 함수로 반환하는 함수를 고차함수라고 부른다.

 

Swift의 고차함수 종류로는 map, filter, reduce 등이 있고, 표준 라이브러리 컨테이너 타입인 Array, Dictionary, Set에 구현되어 있다. 

 

한마디로, Array, Dictionary, Set 타입의 컬렉션 타입은 고차함수인 map, filter, reduce를 사용할 수 있다!

map


map은 호출될 때 인자로 함수를 전달받는데, 그 전달된 함수의 실행 결과를 리턴해주는 함수이다.

 

즉 기존 컨테이너의 데이터를 map 함수로 변형하여 새로운 컨테이너를 생성한다. 

 

따라서 map은 기존 컨테이너 데이터를 유지하면서 값을 변형한 새로운 컨테이너를 생성하고 싶을 때 사용한다. 

let numbers: [Int] = [1,2,3,4,5,6,7,8,9]
let multiple10Numbers = numbers.map{(num: Int) -> Int in
    return num * 10
}

print(multiple10Numbers)// [10, 20, 30, 40, 50, 60, 70, 80, 90]

filter


filter는 말 그대로 컨테이너 내부의 데이터를 걸러서 새로운 컨테이너로 추출하는 함수이다.

 

map은 컨테이너에 속한 모든 원소들의 값을 인자로 들어온 함수를 이용해 변형시켰다면, filter는 컨테이너에 속한 원소들 중 인자로 들어온 함수의 조건에 맞는 원소들만 추출하는 것이다. 

 

여기서 중요한 건!! 새로운 컨테이너로 추출된다는 것을 잊으면 안된다! 기존 컨테이너의 값은 변경되지 않는다. 

 

let numbers: [Int] = [1,2,3,4,5,6,7,8,9]
let evenNumbers = numbers.filter{(num: Int) -> Bool in
    return num % 2 == 0
}

print(evenNumbers) // [2, 4, 6, 8]

reduce


reduce는 한국어로 (크기, 양 등을) 줄이다, 축소하다는 의미를 갖고 있다.

 

이처럼 reduce 함수는 컨테이너에 속한 원소들을 하나로 합쳐주서 줄여주는 함수이다.

 

Array에 속한 Int 타입의 값들을 합쳐보자.

  • for-loop
let numbers: [Int] = [1,2,3,4,5,6,7,8,9]

var sum = 0;
for number in numbers {
    sum += number
}
 
print(sum) // 45
  • reduce
let numbers: [Int] = [1,2,3,4,5,6,7,8,9]

let sum = numbers.reduce(0, {(result: Int, current: Int) -> Int in
    return result + current
})

print(sum) // 45

reduce를 살펴보면, 인자로 0과 클로저 함수가 들어가 있다. 

 

여기서 0은 초기값이다. 그리고 클로저 함수로 numbers의 모든 원소를 더한다.

 

만약 초기값이 5라면 어떻게 될까?

let numbers: [Int] = [1,2,3,4,5,6,7,8,9]

let sum = numbers.reduce(5, {(result: Int, current: Int) -> Int in
    return result + current
})

print(sum) // 50

5부터 numbers의 원소들을 더했으므로 50이 나온다.