study record

[Swift] Swift 고차함수(map 시리즈, reduce, filter) 본문

Swift/스위프트 정리

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

asong 2023. 1. 30. 07:55

고차함수란?

다른 함수를 인자로 전달받거나 실행 결과를 함수로 반환하는 함수.

 

map

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

시퀀스의 값들을 주어진 클로저에서 맵핑하여 그 결과를 포함하는 배열을 리턴한다.

 

Return 값 : 시퀀스의 변형된 값들의 배열.

Parameter : 맵핑 클로저. 

let cast = ["Vivien", "Marlon", "Kim", "Karl"]
let lowercaseNames = cast.map { $0.lowercased() }
// 'lowercaseNames' == ["vivien", "marlon", "kim", "karl"]
let letterCounts = cast.map { $0.count }
// 'letterCounts' == [6, 6, 3, 4]

 

flatMap

func flatMap<SegmentOfResult>(_ transform: (Self.Element) throws -> SegmentOfResult) rethrows -> [SegmentOfResult.Element] where SegmentOfResult : Sequence

시퀀스의 각 값에 주어진 변형을 호출함을 통해 연결된 결과를 포함하는 배열을 리턴한다.

 

Return 값 : 변형된 배열

Parameter : 인자로서 시퀀스의 값을 받아들이고, 시퀀스나 컬렉션을 리턴하는 클로저

 

flatMap은 시퀀스나 컬렉션의 각 값을 변형하여 생산하고 싶을 때 사용한다.

예시에서, map과 flatMap의 결과 차이를 볼 수 있다.

let numbers = [1, 2, 3, 4]

let mapped = numbers.map { Array(repeating: $0, count: $0) }
// [[1], [2, 2], [3, 3, 3], [4, 4, 4, 4]]

let flatMapped = numbers.flatMap { Array(repeating: $0, count: $0) }
// [1, 2, 2, 3, 3, 3, 4, 4, 4, 4]

flat은 평평한이라는 뜻을 가진 단어인만큼 결과를 하나의 배열로 제공하는 것의 차이가 있는 것 같다.

 

s.flatMap(transform) is equivalent to Array(s.map(transform).joined()).

map에다가 joined()메서드를 적용시킨 배열과 flatMap은 동일한 결과를 가진다고 한다.

 

compactMap

func compactMap<ElementOfResult>(_ transform: (Self.Element) throws -> ElementOfResult?) rethrows -> [ElementOfResult]

시퀀스의 각 값을 변형하여 non-nil 결과를 포함하는 배열을 리턴한다.

 

Return 값 : 시퀀스의 각 값의 변형 값의 non-nil 결과를 담은 배열

Parameter : 인자로서 시퀀스의 값을 받아들이고 옵셔널 값을 리턴하는 클로저

 

변형이 옵셔널 값을 만들어낼 때 non-optional 값의 배열을 만들고 싶을 때 사용한다.

let possibleNumbers = ["1", "2", "three", "///4///", "5"]

let mapped: [Int?] = possibleNumbers.map { str in Int(str) }
// [1, 2, nil, nil, 5]

let compactMapped: [Int] = possibleNumbers.compactMap { str in Int(str) }
// [1, 2, 5]

예시처럼 nil값이 나올 때 이를 제외한 값들만 얻을 수 있다.

 

reduce

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

주어진 클로저를 사용하여 시퀀스의 값들을 결합한 결과를 리턴한다.

 

Return 값 : 마지막 축적된 값. 만약 시퀀스에 아무런 값이 없다면 initialResult를 리턴한다.

Parameters : 

  initialResult : 초기 축적 값. nextPartialResult에 처음으로 전달된다.

  nextPartialResult : 축적된 값과 축적될 시퀀스의 값을 결합하는 클로저.

 

reduce(_:_:)를 사용하여 전체 시퀀스의 값들로부터 하나의 값을 생산해낼 수 있다. 

let numbers = [1, 2, 3, 4]
let numberSum = numbers.reduce(0, { x, y in
    x + y
})
// numberSum == 10

reduce가 호출되면 먼저, initialResult인 0과 numbers의 첫번째 값인 1이 합해진다.

이후 반복적으로 리턴 값과 각 시퀀스의 요소가 합해진다. 그리고 더 이상 시퀀스가 없을 때 마지막 리턴 값이 메서드의 리턴값이 된다.

 

만약 시퀀스에 아무 값이 없으면 nextPartialResult는 실행되지 않고, initialResult값이 reduce의 리턴값이 된다.

 

filter

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

주어진 서술부를 만족하는 시퀀스의 요소를 순서대로 포함하는 배열을 리턴한다.

 

Return 값 : 포함된 요소들의 배열

Paramter : isIncluded - 시퀀스의 요소를 가져가서 리턴할 배열에 포함해야할지 판단하는 Boolean 값을 리턴하는 클로저.

 

let cast = ["Vivien", "Marlon", "Kim", "Karl"]
let shortNames = cast.filter { $0.count < 5 }
print(shortNames)
// Prints "["Kim", "Karl"]"

 

forEach

func forEach(_ body: (Self.Element) throws -> Void) rethrows

for 루프에서 시퀀스의 값들에 주어진 클로저를 호출한다.

 

parameter : body - 파라미터로 시퀀스의 값을 가져가는 클로저

 

let numberWords = ["one", "two", "three"]
for word in numberWords {
    print(word)
}
// Prints "one"
// Prints "two"
// Prints "three"

numberWords.forEach { word in
    print(word)
}
// Same as above

같은 결과를 생산하는 두 루프.

 

forEach 사용의 특징

1. break나 continue를 사용할 수 없다.

2. body 클로저에서 return문을 사용하는 것이 유일하게 현재 body에서 나갈 수 있는 것이나 범위 밖으로가 아니다. 다음의 호출을 스킵할 수 없다.

3. forEach는 클로저로 넘겨준다.

 

 

참고

https://developer.apple.com/documentation/swift/sequence/flatmap(_:)-jo2y 

https://developer.apple.com/documentation/swift/sequence/compactmap(_:) 

https://developer.apple.com/documentation/swift/array/foreach(_:)

 

 

 

 

 

 

'Swift > 스위프트 정리' 카테고리의 다른 글

[Swift] Creating and Managing Dispatch Queues  (0) 2023.02.13
[Swift] Dispatch Queues  (0) 2023.02.07
[Swift] Combine 연산자와 CheckedContinuation  (0) 2023.01.29
[Swifit] Combine 기본 예제  (0) 2023.01.15
[Swift] Actor란? - 1  (0) 2022.12.18