[Swift] 20. 고차함수 - 맵, 필터, 리듀스

Hoojeong Kim·2022년 3월 11일
0

Swift Base

목록 보기
22/22
post-thumbnail

고차함수

다른 함수를 전달 인자로 받거나 함수 실행의 결과를 함수로 반환하는 함수를 고차함수라고 한다. 이것이 가능한 이유는, 스위프트의 함수가 1급 객체이기 때문이다.

고차함수의 종류는 다음과 같다.

  • 맵(map)
  • 필터(filter)
  • 리듀스(reduce)

모두 표준 라이브러리의컨테이너 타입(배열, 세트, 딕셔너리 등)에 구현되어 있다.

그렇다면, 지금부터 맵, 필터, 리듀스에 대해 알아보자.

맵(map)

맵은 자신을 호출항 때 매개변수로 전달된 함수를 실행하여 그 결과를 다시 반환해주는 함수이다.

맵을 사용하면 컨테이너가 담고 있던 각각의 값을 매개변수를 통해 받은 함수에 적용한 후 다시 컨테이너에 포장하여 반환한다. 기존 컨테이너의 값은 변경되지 않고 새로운 컨테이너가 생성되어 반환된다. 그래서 맵은 기존 데이터를 변형하는 데 많이 사용한다.


맵은 for-in 구문과 별반 차이가 없다. 다만 코드의 재사용 측면이나 컴파일러 최적화 측면에서 맵의 성능이 더 우수하다.
let numbers = [0, 1, 2, 3]
let mapArray = numbers.map { (number: Int) -> Int in
	return number * 2
}

print("map \(mapArray)")
map [0, 2, 4, 6]

맵을 이용해 numbers의 요소들을 불러와 2씩 곱한 값을 반환한다. mapArray 변수에는 numbers의 요소인 number에 각각 2가 곱해진 새로운 배열이 저장된다.


앞서 배운 클로저 표현의 간소화 토대로 mapArray를 간소화 해보면 다음과 같다.
let mapArray = numbers.map { $0 * 2 }

이처럼 맵은 컨테이너 내의 기존 데이터를 변형하여 새로운 컨테이너를 생성한다.

필터(filter)

필터는 말 그대로 컨테이너 내부의 값을 걸러서 추출하는 역할을 한다. 맵과 마찬가지로 새로운 컨테이너에 값을 담아 반환하지만, 맵처럼 기존 데이터를 변형하는 것이 아니라 특정 조건에 맞게 걸러낸다.

let numbers2 = [10, 5, 20, 13, 4]
let filterArray = numbers2.filter { (number: Int) -> Bool in
	return number > 5
}

print("filter \(filterArray)")
filter [10, 20, 13]

필터 함수를 사용하여 numbers2의 요소에 접근한다. 이때, 요소가 5보다 큰 값을 걸러내고, filterArray 변수에는 5보다 큰 값들만 존재하는 새로운 배열이 저장된다.


앞서 배운 클로저 표현의 간소화 토대로 filterArray를 간소화 해보면 다음과 같다.
let filterArray = numbers2.filter { $0 > 5 }

이처럼 필터는 컨테이너 내부의 값을 걸러내어 새로운 컨테이너로 추출한다.

리듀스(reduce)

리듀스는 컨테이너 내부의 요소를 하나로 합하는 역할을 한다.

리듀스를 사용해 numbers3의 요소를 모두 더해보자.

let numbers3 = [1, 2, 3, 4, 5]
let reduceResult = numbers3.reduce(0) { (result: Int, element: Int) -> Int in
	print("\(result) + \(element)")
    return result + element
}

print("reduce \(reduceResult)")
0 + 1
1 + 2
3 + 3
6 + 4
10 + 5
reduce 15

리듀스의 첫 번째 매개변수에 초깃값을 0으로 설정하고 두 번째 매개변수인 클로저를 보면 result와 element를 더해 반환한다.

💡 여기서 잠깐!

리듀스의 첫 번째 매개변수는 초깃값으로부터 출발하여 마지막 요소까지 순회하는 내내의 결과값이다.
리듀스의 두 번째 매개변수는 현재 순회하고 있는 요소의 값이다.


앞서 배운 클로저 표현의 간소화 토대로 reduceResult를 간소화 해보면 다음과 같다.
let mapArray = numbers.map { $0 + $1 }

이처럼 리듀스는 컨테이너 내부의 요소를 더하거나 빼는 등의 연산을 수행하여 하나로 합칠 수 있다.
profile
나 애기 개발자 👶🏻

0개의 댓글