flatMap
compactMap
flatMap
: 배열의 각 원소에 대해 클로저 안에서 정해진 처리를 한 다음, 처리된 값들의 배열을 반환한다.func flatMap<SegmentOfResult>(_ transform: (Self.Element) throws -> SegmentOfResult) rethrows -> [SegmentOfResult.Element] where SegmentOfResult : Sequence
SegmentOfResult
라는 제네릭을 사용한다. 그 안의 원소에 적합한 처리를 해서 반환하며, 이 과정에서 오류가 일어날 수 있다. SegmentOfResult
는 Sequence
프로토콜을 준수해야 한다.Sequence
프로토콜은 간단히 말하면 원소에 순차적으로 접근할 수 있음을 나타내는 프로토콜이다. 0...3
처럼 범위를 나타내는 것이 Sequence
프로토콜에 부합한다.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]
let flattened = mapped.flatMap { $0 }
// [1, 2, 2, 3, 3, 3, 4, 4, 4, 4]
compactMap
: 배열의 각 원소에 대해 클로저 안에서 정해진 처리를 한 다음, 처리된 값들 중 nil이 아닌 것들의 배열을 반환한다.flatMap
이 쓰이던 용도 중 일부를 계승한다.flatMap
은 세 가지 작업을 했다. 배열을 평탄화하고, nil
을 제거하고, 옵셔널 바인딩하는 것.nil
제거 및 옵셔널 바인딩의 기능이 compactMap
으로 이관되었다.func compactMap<ElementOfResult>(_ transform: (Self.Element) throws -> ElementOfResult?) rethrows -> [ElementOfResult]
map
과 가장 많이 비교된다.// 공식 문서에서 발췌
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]
flatMap
과 compactMap
이 같은 결과를 반환한다.compactMap
은 flatMap
과 가깝다고 생각했는데, 오히려 map
과 더 가까운 인상을 받았다.flatMap
을 고수하고자 하는 사람도 있을 것이다. 팀마다 다를 것이고, 어쨌든 작동은 되기 때문. 생각해볼 문제다. https://developer.apple.com/documentation/swift/sequence/2905332-flatmap
https://developer.apple.com/documentation/swift/sequence/2950916-compactmap
https://developer.apple.com/documentation/swift/sequence
https://jinshine.github.io/2018/12/14/Swift/22.%EA%B3%A0%EC%B0%A8%ED%95%A8%EC%88%98(2)%20-%20map,%20flatMap,%20compactMap/