develop
Higher Order Functions 고차함수 본문
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 |