[고차함수] map, flatMap, compactMap 비교

Lily·2021년 11월 21일
0

오늘은 Swift가 제공하는 고차함수 중 map, flatMap, compactMap의 차이점에 대해 알아보도록 하겠습니다.

세개의 함수 모두 공통적으로 "map"을 포함하고 있습니다.
map에서 파생된 variation이 flatMap, compactMap인 것 같습니다.

그럼 먼저 map에 대해 알아보겠습니다.

map(_:)


Returns an array containing the results of mapping the given closure over the sequence’s elements.

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

🍎 Developer Doucumentation : map(_:)

"시퀀스의 요소를 순회하며 클로저에 매핑한 결과를 새로운 배열로 반환한다."고 설명합니다.


map을 사용해보겠습니다.

// map 예시 코드
let iceCream = ["Mint Choco", "Rainbow Sherbet", "Mom is Alien", "Cherry jubiler"]

let lowercaseNames = iceCream.map { (taste: String) -> String in
    return taste.lowercased()
} 
let lowercaseNames = iceCream.map { $0.lowercased() } // 축약형

// 'lowercaseNames' == ["mint choco", "rainbow sherbet", "mom is alien", "cherry jubiler"]

map이 하는 기능을 정리해보자면,

💥 시퀀스의 요소를 주어진 클로저의 인자로 전달해서 반환된 값을 새로운 배열로 만들어 반환합니다.
시퀀스를 동일한 클로저로 변형해서 새로운 배열로 만드는 기능이네요!


flatMap(_:)


Returns an array containing the concatenated results of calling the given transformation with each element of this sequence.

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

🍎 Developer Doucumentation : flatMap(_:)

"시퀀스의 각 요소의 transformation(함수)에 따른 결과를 연결된 결과의 배열로 반환한다"고 설명합니다.

map의 설명에 "연결된 결과"라는 키워드가 더 추가된 내용입니다. 연결된 결과가 무엇을 의미하는지 탐구해보겠습니다🧐

선언부를 보면 transform을 거쳐 반환된 결과의 배열이 아닌, 결과의 요소의 배열로 반환해주고 있습니다.

예를 들어 transform을 하는 클로저가 또 시퀀스 또는 배열이나, 컬렉션을 반환한다면 map의 반환 값은 2차원 배열이 될 것입니다.

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]]

이런 상황에서 flatMap은 배열의 요소만을 꺼내어 1차원의 배열로 만들어 리턴해줍니다.

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

정리하자면 flatMap은

💥 map + 반환되는 배열을 flat하게 만들어주는 기능이 추가된 메서드입니다.


compactMap(_:)


Returns an array containing the non-nil results of calling the given transformation with each element of this sequence.

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

🍎 Developer Doucumentation : compactMap(_:)

"시퀀스의 각 요소의 transformation(함수)에 따른 non-nil 결과의 배열로 반환한다"고 설명합니다.

만약 transform이 옵셔널값을 리턴한다면, 그 중 nil은 모두 제거하고 옵셔널은 언래핑된 값만 추출해서 배열에 담아 리턴합니다.

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]

compactMap은

💥 map + 반환되는 결과 중 nil이 아닌 결과만 거르는 기능이 추가된 메서드입니다.


정리

map : 시퀀스의 요소를 주어진 클로저의 인자로 전달해서 반환된 값을 새로운 배열로 만들어 반환
flatMap : map + 반환되는 배열을 flat하게 만들어서 반환
compactMap : map + 반환되는 결과 중 nil이 아닌 결과만 반환

profile
i🍎S 개발을 합니다

0개의 댓글