Swift

Swift - 고차함수 (map, filter, reduce)

iosos 2023. 7. 11. 17:55

* 고차함수 (Higher-order Function)

- 다른 함수를 인자로 받거나 함수를 반환하는 함수

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

 

 

* 종류

  • map
  • filter
  • reduce
  • forEach
  • compactMap
  • FlatMap

 


map 함수

- 컨테이너(예: 배열)의 각 요소에 변환(transform)을 적용하여 새로운 컨테이너를 생성

- 변환은 클로저(익명 함수)를 사용하여 수행 

 

 

기본 형식

func map<T>(_ transform: (Element) throws -> T) rethrows -> [T]

- Element : 컨테이너 요소 타입

- T : 반환 후 요소 타입

- transform : 매핑 클로저로, 컨테이너의 각 요소에 대해 적용되는 변환 작업 정의 

- 리턴 타입 : 컨테이너의 변환된 요소를 포함하는 배열을 반환 

 

 

 

예) Int 타입의 배열의 각 요소를 제곱하는 예제

 

for문 사용

// for 문 사용
let numbers = [1, 2, 3, 4, 5]
var forUseSquaredNumbers: [Int] = []

for number in numbers {
    let squared = number * number
    forUseSquaredNumbers.append(squared)
}
print(forUseSquaredNumbers) // 출력: [1, 4, 9, 16, 25]

- numbers 배열의 각 요소에 대해 number * number 연산을 수행하여 새로운 squared 변수에 저장 후 forUseSquaredNumbers 배열에 추가하는 과정을 반복

 

 

 

map 함수 사용

// map 함수 사용
let numbers = [1, 2, 3, 4, 5]
let mapUseSquaredNumbers = numbers.map { $0 * $0 }
print(mapUseSquaredNumbers) // 출력: [1, 4, 9, 16, 25]

- numbers 배열의 각 요소에 클로저 '$0 * $0'를 적용하여 제곱 값을 계산

- map 함수는 이러한 변환을 모든 요소에 적용하고 변환된 값을 새로운 mapUseSquareNumbers 에 저장 

 

 

 

→  map 함수는 코드의 가독성을 높이고 변환 로직을 간결하게 표현 가능, 내부적으로 최적화되어 성능상의 이점을 가짐

 

 

 


Filter 함수

- 컨테이너의 요소 중 조건을 만족하는 요소만 필터링하여 새로운 컨테이너를 생성

- 조건을 클로저를 사용하여 지정 

 

 

기본 형식

func filter(_ isIncluded: (Self.Element) throws -> Bool) rethrows -> [Self.Element]

- Element : 컨테이너의 요소 타입

- 클로저 isIncluded : 컨테이너의 각 요소에 대해 실행되는 조건 정의 

- 조건을 만족하는 요소는 결과로 반환 

 

 

 

 

 filter 함수를 사용하여 배열에서 짝수를 필터링하는 예제

let numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
let evenNumbers = numbers.filter { $0 % 2 == 0 }
print(evenNumbers) // 출력: [2, 4, 6, 8, 10]

- numbers 배열의 각 요소에 대해 클로저 '$0 % 2 == 0' 를 적용하여 짝수인지 여부 확인

- filter 함수는 이러한 조건을 만족하는 요소만을 선택하여 새로운 배열로 반환 

 

 

 

문자열 배열에서 길이가 5보다 큰 문자열만 필터링하는 예제

let names = ["Alice", "Bob", "Charlie", "David", "Eve"]
let filteredNames = names.filter { $0.count > 5 }
print(filteredNames) // 출력: ["Charlie"]

 

→ filter 함수는 다양한 데이터 타입에 대해 사용 가능하며, 컨테이너 요소 중 특정 조건을 만족하는 요소만 선택하는 작업에서 유용

 

 

 

 


Reduce 함수

- 컨테이너의 요소들을 결합하여 단일 값으로 축소

- 결합은 클로저를 사용하여 수행 

 

 

기본 형식

func reduce<Result>(_ initialResult: Result, _ nextPartialResult: (Result, Element) throws -> Result) rethrows -> Result

- Result : 축소 연산의 결과 타입

- Element : 컨테이너의 요소 타입 

- initailResult : 초기값으로 사용

- nextPartialResult : 클로저, 컨테이너의 각 요소와 현재 축소 결과를 받아 다음 단계의 축소 결과를 계산 

 

 

reduce 함수를 사용하여 배열의 모든 요소를 합산하는 예제

let numbers = [1, 2, 3, 4, 5]
let sum = numbers.reduce(0) { $0 + $1 }
print(sum) // 출력: 15

- numbers 배열의 각 요소에 대해 클로저 '$0 + $1' 를 적용하여 덧셈 수행

- reduce 함수는 첫 번째 읹인 초기값 '0'을 시작으로 첫 번째 요소부터 순차적으로 클로저 적용하여 축소 결과 계산

 

 

 

 

reduce 함수를 사용하여 배열의 요소들을 문자열로 이어붙이는 예제

let words = ["Hello", " ", "World", "!"]
let sentence = words.reduce("") { $0 + $1 }
print(sentence) // 출력: "Hello World!"

- "" 빈 문자열을 초기값으로 사용하고 각 요소들을 순차적으로 이어 붙임 

 

 

 

문자열에서 숫잠 문자만 필터링하고, 각 숫자 문자를 정수로 변환하여 모두 합산하여 결과를 반환하는 예제

import Foundation

func solution(_ my_string: String) -> Int {
    return my_string.filter { $0.isNumber }.map { Int(String($0))! }.reduce(0, +)
}

let myString = "456abc123"
let result = solution(myString)
print(result) // 출력: 18 (숫자 4 + 숫자 5 + 숫자 6 + 숫자 1 + 숫자 2 + 숫자 3)

- 'reduce(0, +)' 의 의미가 'reduce(0){$0 + $1}' 과 같은 의미 

 

→ reduce 함수는 다양한 종류의 축소 작업에 활용되며, 컨테이너 요소들을 조합하여 원하는 결과를 도출하는 데 유용

 

 

 

 

참고) https://velog.io/@un1945/Swift-%EA%B3%A0%EC%B0%A8%ED%95%A8%EC%88%98-Higher-order-Function 

 

[Swift] 고차함수 (map, filter, reduce)

안녕하세요! Kio입니다 👻오늘은 고차함수(Higher-order Function) 에 대해 알아볼까 하는데요. 고차함수에는 다음과 같은 여러 종류가 있습니다.map, filter, reduce, forEach, compaceMap, FlatMap 오늘은 그 중에

velog.io