develop

Higher Order Functions 고차함수 본문

iOS

Higher Order Functions 고차함수

pikachu987 2021. 1. 12. 10:13
반응형
let array: [Int] = [1, 2, 3, 5, 7, 12, 24, 130]

for (index, element) in array.enumerated() {
    print("index: \(index), element: \(element)")
}

고차함수 라고 한다.

일반적으로 array에 있는 값들을 출력을 할때 아래와 같은 코드로 하게 된다.

 

Swift에서 index를 알고 싶으면 아래와 같은 코드로 하게 된다.

let array: [Int] = [1, 2, 3, 5, 7, 12, 24, 130]

for element in array {
    print(element)
}

 

forEach

위의 코드를 forEach 고차함수로 적용하면 아래와 같은 코드가 된다.

array.forEach({ print($0) })

array.enumerated().forEach({ print("index: \($0.offset), element: \($0.element)") })

 

$0 대신 변수명을 적을 수도 있다.

array.forEach({ element in
    print(element)
})

array.enumerated().forEach({ (index, element) in
    print("index: \(index), element: \(element)")
})

 

forEach는 for문과 비슷하게 element값을 반복할수 있다.

딕셔너리 형태도 사용 가능하다.

let dict: [String: AnyObject] = [
    "name": "Kim" as AnyObject,
    "age": 27 as AnyObject
]

dict.forEach({ print("key: \($0.key), value: \($0.value)") })

 

filter

원하는값만 나오게 할 수 있다.

let filterArray = array.filter ({ value -> Bool in
    return value < 10
})

 

위의 코드보다 더 간단하게 줄이면

let filterArray = array.filter({ $0 < 10 })

 

map

let mapArray = array.map({ "\($0)" })

이렇게 하면 타입이 [Int]였던게 [String]으로 리턴되어서 나온다.

 

 

compactMap

flatMap은 Swift 4.1부터 deprecated되었다.
'flatMap' is deprecated: Please use compactMap(_:) for the case where closure returns an optional value
let compactMapArray = array.compactMap({ "\($0)" })

map과 마찬가지 타입이 [Int]였던게 [String]으로 리턴되어서 나온다.

let array = ["1", "hi", "2", "good"]

let mapArray = array.map({ Int($0) })
let compactMapArray = array.compactMap({ Int($0) })

print("mapArray: \(mapArray)")

print("compactMapArray: \(compactMapArray)")
mapArray: [Optional(1), nil, Optional(2), nil]
compactMapArray: [1, 2]

 

map과 compactMap의 차이점은 map은 옵셔널로 리턴을 했을때는 옵셔널의 형태로 반환이 된다.

compactMap은 옵셔널로 리턴을 했을 때 nil의 값이 제외되고 옵셔널이 벗겨져서 나오게 된다.

두 함수 다 필요한 상황들이 있다.

 

sorted

고차함수로 sort를 할 수 있다.

array.sorted(by: { $0 > $1 })

 

 

reduce

reduce는 초기값을 줄 수 있고 어떻게 계산을 할지 정의할수 있다.

let value = array.reduce(1000000) { (result, value) -> Int in
    return result + value
}

더 간단하게 하면

let value2 = array.reduce(1000000, { $0 + $1 })

더 간단하게 하면

let value3 = array.reduce(1000000, +)

이렇게 까지 생략할수 있다.

 

Chaining

let array: [Int] = [1, 2, 3, 5, 7, 12, 24, 130]

let value = array.filter({ $0 < 10 })
            .sorted(by: { $0 > $1 })
            .map({ "\($0)" })
            .reduce("", { "\($0)\($1)" })
print(value)
75321

array중에 10 이하인것들만 가져오면 1, 2, 3, 5, 7

sorted로 큰수로 오름차순으로 7, 5, 3, 2, 1

map으로 String을 만들면 “7”, “5”, “3”, “2”, “1”

reduce로 문자열을 합치면 75321이 된다.

 

Higher Order Functions 만들기

map의 형태를 보면 아래와 같이 되어 있다.

public struct Array<Element> {
    public func map<T>(_ transform: (Element) throws -> T) rethrows -> [T]
}

 

이것을 보고 customMap을 만들어 보면 아래와 같이 만들수 있다.

extension Array {
    func customMap<T>(_ transform: (Element) -> T) -> [T] {
        var array = [T]()
        for element in self {
            array.append(transform(element))
        }
        return array
    }
}

 

간단하게 이렇게 곱셈을 할 수 있는 함수를 아래와 같이 만들어 볼수 있다.

extension Array where Element == Int {
    func multiplication(_ value: Int) -> [Int] {
        var array = [Element]()
        for element in self {
            array.append(element * value)
        }
        return array
    }
}

 

반응형

'iOS' 카테고리의 다른 글

AccessControl 접근 한정자  (0) 2021.01.14
where Keyword (for의 where, switch 의 where, extension의 where, func의 where)  (0) 2021.01.13
AutoLayout  (0) 2021.01.11
Blocking, Non-blocking  (0) 2021.01.10
Semaphore  (0) 2021.01.09
Comments