카테고리 없음

swift 고참함수 compactMap, flatMap에 대해 알아봅시다.

kingarthur 2024. 6. 18. 18:22

compactMap

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

컨테이너의 각 요소를 조건을 지정하여 호출할 때, nil 이 아닌 배열을 반환합니다.



선언 (Declaration)

Apple 에서는 compactMap 이 아래처럼 정의되어 있네요.

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



매개변수 (Parameters)

transform

  • transform 는 컨테이너의 요소를 매개변수로 받아 선택적 값을 반환하는 클로저입니다.



예시 (Discussion)

예시를 통해 compactMap 을 더 알아볼게요!
다음 예제는 같은 결과를 출력합니다.

 

map

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

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

 

compactMap

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

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

 

map 을 사용했을 때는 Optional 이지만
compactMap 을 사용하니 Int 에 해당하는 값만 들어갔네요? 👀

그 이유는 compactMap 이 옵셔널 바인딩의 기능을 가지고 있기 때문입니다.
map 의 원래 기능에서 옵셔널 제거까지 가능합니다.
map 보다 단순하고 가볍게 바꿀 수 있어서 compactMap 으로 짓지 않았나 싶네요 👻

// nil 값이 올수 있기에 ?? "" 빈배열 
let input = readline() ?? ""
// 처음 클로저가 변환되면 캐릭터 타입으로 되기 때문에 스트링 으로 변환 후 인트로 다시 변환 하고
// compacMap 자동으로 nil 값 제거 
let compcatMaps = (0...10).map {String($0)}.compactMap {Int($0)}


이렇게 사용도 가능은 하다~.

flatMap

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

컨테이너의 각 요소를 사용하여 지정된 조건을 호출할 때, 순차적인 결과의 배열을 반환합니다.

말이 너무 어려운데요 😭
쉽게 말하면 중첩된 배열을 제거하고 평평한 배열(flattened array)을 리턴합니다.

 

선언 (Declaration)

Apple 에서는 flatMap 은 아래처럼 정의되어 있네요.

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



매개변수 (Parameters)

transform

  • transform 는 컨테이너의 요소를 매개변수로 받아, 컨테이너로 반환하는 클로저입니다.



예시 (Discussion)

예시가 빠질 수 없겠죠?
전 예시 없이는 이해할 수 없습니다... 😱

 

예시1 (2차원 배열)

let numbers = [[1], [2, 3], [4, 5, 6], [7, 8, 9, 10]]

let flatMapped = numbers.flatMap { $0 }
print(flatMapped)
// [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

flatMap 을 사용하니 2차원 배열이 1차원 배열이 되어
평평한 배열(flattened array) 을 리턴하였네요!

 

예시2 (3차원 배열)

let numbers = [[[1], [2, 3], [4, 5, 6], [7, 8, 9, 10]]]

let flatMapped = numbers.flatMap { $0 }
print(flatMapped)
// [[1], [2, 3], [4, 5, 6], [7, 8, 9, 10]]

let doubleFlatMapped = flatMapped.flatMap { $0 }
print(doubleFlatMapped)
// [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

3차원 배열도 flatMap 2번을 사용하니
평평한 배열(flattened array)이 되었습니다.

 

let numbers = [[[1], [2, 3], [4, 5, 6], [7, 8, 9, 10]]]

let flatMapped = numbers.flatMap { $0 }.flatMap { $0 }
print(flatMapped)
// [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

2번을 사용하고자 한다면
위처럼 .flatMap { $0 }.flatMap { $0 } 을 사용해도 됩니다!

이처럼 예시를 통해 알 수 있듯 flatMap 중첩된 배열을 제거합니다.
중첩이 많이 되어있다면 그 만큼 사용해보면 되겠죠? 🥳

아주 좋은 기능을 알게 되었습니다. 다음에 꼭 실전에 활용해보기