[Swift] flatMap & compactMap
flatMap과 compactMap의 차이에 대해 기록해보겠습니다.
아래 그림과 같이, Swift 4.1부터는 원래 사용되었던 flatMap이 deprecated되고 새로운 flatMap과 compactMap으로 바뀝니다.
새롭게 바뀐 flatMap은 2차원 배열에서 1차원 배열로 flatten하게 만들어주는 역할로 쓰입니다. 즉, 내부의 컨텍스트를 같은 위상으로 만들어줍니다.
var nums = [[1,2,3],[4,5],[6]]
let flatten = nums.flatMap { $0 } // [1,2,3,4,5,6]
let compacted = nums.compactMap { $0 } // [[1,2,3],[4,5],[6]]
compactMap은 nil을 제거하고 옵셔널 바인딩이 필요할 때 사용합니다.
var num = [1,2,3,4,nil]
let flattenedNum = nums.flatMap {$0}
// [1, 2, 3, 4]
let compactedNum = num.compactMap { $0 }
// [1, 2, 3, 4]
var nums = [[1,2,3,nil],[4,5,nil],[6]]
let flattenedNums = nums.flatMap { $0 }
// [Optional(1), Optional(2), Optional(3), nil, Optional(4), Optional(5), nil, Optional(6)]
let compactedNums = nums.compactMap { $0 }
// [[Optional(1), Optional(2), Optional(3), nil], [Optional(4), Optional(5), nil], [Optional(6)]]
1차원 배열에서는 compactMap으로 nil을 제거하는 것을 볼 수 있고 flatMap과 결과가 같은 이유는 deprecated된 flatMap으로 실행되었기 때문입니다.
2차원 배열에서 flatMap은 nil을 제거하지 못 하지만 1차원 배열로 만들어주는 것을 볼 수 있습니다. compactMap은 2차원 배열일 때는 nil을 제거하지 않습니다.
새로운 flatMap과 compactMap으로 2차원 배열을 1차원 배열로 만들고 nil을 제거하려면 ??
var nums = [[1,2,3,nil],[4,5,nil],[6]]
let result = nums.flatMap { $0 }.compactMap { $0 }
// [1, 2, 3, 4, 5, 6]
체이닝을 통해 flatMap으로 1차원 배열로 만들고 compactMap을 통해 nil을 제거해줍니다.
이를 통해, 알 수 있던 점은 Swift4.1 이전의 flatMap을 역할에 따라 새로운 flatMap과 compactMap으로 나눠준 것을 알 수 있었습니다.
- flatMap(_:) - 내부 컨텍스트를 같은 위상으로 만들어준다.
- compactMap(_:) - nil을 제거하고 옵셔널 바인딩을 해준다.
참고:
developer.apple.com/documentation/swift/sequence/2905332-flatmap
developer.apple.com/documentation/swift/sequence/2907182-flatmap
developer.apple.com/documentation/swift/sequence/2950916-compactmap
스위프트 프로그래밍(3판): 객체지향, 함수형, 프로토콜 지향 패러다임까지 한 번에!(Swift 5)