본문 바로가기
Swift

Swift High Order Function Summary

by HaningYa 2020. 10. 6.
728x90

https://dev.to/bhupendra1011/higher-order-functions-from-scratch-functional-js-3ii0

고차함수란

함수를 다루는 함수

  • 하나 이상의 함수를 인자로 받는다.
  • 함수를 결과로 반환한다.

Swift 고차함수 종류

  • Map
  • Filter
  • Reduce
  • CompactMap
  • FlatMap

Map

  • 배열 내부의 값을 하나씩 mapping 하는 역할
  • 각 요소에 대한 값을 변경 하고자 할때 사용하고 결과를 배열 상태로 반환
func map<T>(_ transform: (String) throws -> T) rethrows -> [T]

예제 코드 (배열의 값을 2배씩 곱해진 배열을 리턴)

var arr : [Int] = [1,2,3,4,5,6,7,8,9,10]
//일반적
var doubledArr = arr.map({ (number : Int) -> Int in 
    return number*2
})
//후행클로져
var doubledArr2 = arr.map{ $0*2 }

print(doubledArr2) //[2, 4, 6, 8, 10, 12, 14, 16, 18, 20]
print(doubledArr2) //[2, 4, 6, 8, 10, 12, 14, 16, 18, 20]

Filter

  • 각 항목들을 비교하여 일치하는 결과물을 가진 새로운 배열 반환
func filter(includeElement: (T) -> Bool) -> Array<T>

예제 코드 (짝수 값만 가지는 배열을 리턴)

var arr : [Int] = [1,2,3,4,5,6,7,8,9,10]


var evenArr = arr.filter({ (number: Int) -> Bool in 
    return number%2==0
})
var evenArr2 = arr.filter { $0%2==0 }
print(evenArr) //[2, 4, 6, 8, 10]
print(evenArr2)//[2, 4, 6, 8, 10]

Reduce

  • 배열의 각 항목을들 재귀적으로 클로저를 적용시켜 하나의 값을 만듬
func reduce<U>(initial: U, combine: (U, T) -> U) -> U

예제 코드 (배열의 합을 구함)

var arr : [Int] = [1,2,3,4,5,6,7,8,9,10]

var sum = arr.reduce(0, { (first: Int, second: Int) -> Int in 
    return first + second
})
var sum2 = arr.reduce(0) {$0 + $1}
print(sum) //55
print(sum2)//55

CompactMap

  • nil 을 제거하고 optional binding을 해줌 
func compactMap<ElementOfResult>(_ transform: (Int?) throws -> ElementOfResult?) rethrows -> [ElementOfResult]

예제 코드 (Nil 값 제거, 제거후 String 형변환)

let arrWithNil = [1,2,nil,4,5,6]
let arrWithoutNil = arrWithNil.compactMap{ $0 }
let arrWithoutNilToString = arrWithNil.compactMap { $0 }.map { String($0) }
print(arrWithNil)
print(arrWithoutNil)
print(arrWithoutNilToString)

//[Optional(1), Optional(2), nil, Optional(4), Optional(5), Optional(6)]
//[1, 2, 4, 5, 6]
//["1", "2", "4", "5", "6"]

FlatMap

  • 배열 내부의 값을 flatten 하게 만들어줌 -> 다차원 배열 다룰때 쓰임
  • nil 을 제거하고 optional binding을 해줌 근데 Swift4.1 부터는 compactMap 사용
func flatMap<SegmentOfResult>(_ transform: ([Int]) throws -> SegmentOfResult) rethrows -> [SegmentOfResult.Element] where SegmentOfResult : Sequence

예제 코드 (2차원 배열을 nil 제거 후 일차원 배열로 변환)

let multiArray = [ [1,3,5,nil], [2,nil,6] ]
let multiArrayToString = multiArray.flatMap { $0 }.compactMap{ $0 }
print(multiArray)
print(multiArrayToString)

//[[Optional(1), Optional(3), Optional(5), nil], [Optional(2), nil, Optional(6)]]
//[1, 3, 5, 2, 6]

연습

nil이 포함된 2차원 배열 의 합을 2진수로 바꿔서 String을 리턴해라

  1. flatMap으로 2차원 배열을 1차원으로 flat 시킴
  2. compactMap으로 nil값을 없앰
  3. reduce로 합을 구함
  4. String( (Int), radix: (Int) ) 로 진수 변환
let input = [[3,10,nil], [9, -1, nil, 2], [3,10,nil] , [4, -5, nil, 2]]
let ouput = String(input.flatMap{$0}.compactMap{ $0 }.reduce(0){$0 + $1}, radix: 2)
print(ouput) //100101

Map vs CompactMap vs FlatMap

배열 각각의 값을 변형하고 배열을 리턴할 때 Map을 쓰는데

  • Nil 에 관한 처리가 필요없거나 직접 처리할 경우 Map
  • Optional Binding이 필요할 땐 CompactMap
  • 다차원 배열의 차원을 낮추고 싶을 땐 FlatMap

튜플배열 HOF 후행클로저 사용 예시

원본 튜플배열

let tupleArr : [(String,Int)] = [ ("A",0), ("B",1), ("C", 2), ("D", 3) ]

[(String, Int)] -> [(String,String)] 형변환

let strArr : [(String,String)] = tupleArr.map{ ($0.0,"\($0.1)") }
print(strArr) //[("A", "0"), ("B", "1"), ("C", "2"), ("D", "3")]

Int 의 합

let sumOfInt : Int = tupleArr.reduce(0){ $0 + $1.1 }
print(sumOfInt) //6

String 합치기

let sumOfStr : String = tupleArr.reduce(""){ $0 + $1.0}
print(sumOfStr) //ABCD

 

728x90

'Swift' 카테고리의 다른 글

Swift Closure (일급객체 함수)  (0) 2021.03.25
Swift where syntax  (0) 2020.10.27
[DI] Initializer로 Swift 의존성 주입하기  (0) 2020.09.03
ARC - Automatic Reference Counting  (0) 2020.08.24
Swift: 프로퍼티와 메서드  (0) 2020.07.13

댓글