ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • map flatMap 그리고 compactMap
    iOS 2019. 12. 30. 18:27
    728x90

    오늘은 비슷한 듯 다른 map 3총사에 대해 알아보겠습니다.


    Map

    먼저 가장 기본이 되는 map 입니다.

    map의 정의는 다음과 같습니다.

    배열 내부의 값을 하나씩 mapping 해 각 요소에 대한 값을 변경한 새로운 배열을 원할 때 사용합니다.

    각 요소의 값을 변경한 뒤 배열로 다시 리턴해줍니다.

    [Int] 안의 모든 원소의 제곱한 배열을 원한다면?

    let a = [1, 2, 3, 4, 5] 
    
    let squared = a.map { 
      $0 * 2 
    } 
    
    print(squared) // [2, 4, 6, 8, 10]

     

    flatMap 그리고 compactMap

    flatMap 도 compactMap도 둘다 맵은 맵이니 하는 일은 비슷합니다만 어떤 차이가 있을까요?

    먼저 이 녀석들도 정의부터 살펴보고 가겠습니다.

    compactMap

    먼저 compactMap의 탄생 배경부터 살펴보겠습니다. 

    Deprecated 된 flatMap의 정의를 보면 compactMap과 완전히 동일하죠? 네 맞습니다.
    원래 flatMap이 하던 한 가지 일을 compactMap으로 나눠서 각 쓰임에 따라 명확히 분류 했다고 보시면 됩니다.
    설명을 읽어보면 nil이 아닌 결과를 가진 배열을 리턴해준다고 되어있는데요, 한마디로 nil 값을 제거해준다는거네요!

    예제를 살펴보죠

    let a = [1, 2, 3, nil, 4, 5]
    
    let squared = a.compactMap {
        $0
    }.map {
        $0 * 2
    }
    
    print(squared)

    앞의 예제와 같지만 nil이 들어있다는 점이 차이입니다. 이때는 a의 타입이 [Int?] 이 되어서 앞의 예처럼 바로 map을 사용할 수 없고 옵셔널 바인딩 후에 사용해야 합니다. 이 옵셔널 바인딩 과정을 해주는게 바로 compactMap 입니다. 

    flatMap

    그럼 이제 마지막으로 flatMap을 살펴보겠습니다.

    flat을 사전에서 찾아보면 고른, 평평한 이라는 뜻인데요. 배열을 평평하게 펴준다면 하면 어떤 의미일까요? 

    고차원 배열을 한꺼풀 벗겨서 하나 아래의 차원으로 바꿔준다는 의미입니다.

    예제를 바로 살펴볼게요

    let a = [[1, 2, 3], [4, 5, 6]]
    
    let flatMapTest = a.flatMap {
        $0
    }
    
    print(flatMapTest) // [1, 2, 3, 4, 5, 6]
    

     

    네 이렇게 2차원 배열이 1차원 배열이 되었습니다. 간단하죠?? 

    그렇다면 nil이 포함되어 있다면 어떻게 될까요?

    let a = [[1, 2, 3], [nil, 4, 5, 6]]
    
    let flatMapTest = a.flatMap {
        $0
    }
    
    print(flatMapTest) // [Optional(1), Optional(2), Optional(3), nil, Optional(4), Optional(5), Optional(6)]
    

     

    네 기본 원리만 이해하고 있으면 전혀 어려울 건 없어요. 그냥 [[Int?]] -> [Int?]로 한 차원 내려갔을 뿐입니다.

    그렇다면 3차원은???

    let a = [[1, 2, 3], [nil, 4, 5, 6, [7, 8]]]
    
    let flatMapTest = a.flatMap {
        $0
    }
    
    print(flatMapTest) // [Optional(1), Optional(2), Optional(3), nil, Optional(4), Optional(5), Optional(6), Optional([7, 8])]
    
    

    네 정말 간단하게 [[[Int?]]] -> [[Int?]] 이 되었습니다. 

    어려울 거 하나도 없죠?!! 

    그동안 flatMap이라는 이름으로 하던 2가지 compactMap, flatMap으로 분리해
    각 역할을 명확하게 해준 깊은 애플님의 깊은 뜻을 다시한번 느낄 수 있네요.. :)

    여기서 잠깐!

    그럼 앞의 2차원 배열에서 compactMap을 사용하면 어떻게 될까요?

    let a = [[1, 2, 3], [nil, 4, 5, 6]]
    
    let flatMapTest = a.compactMap {
        $0
    }
    
    print(flatMapTest) // [[Optional(1), Optional(2), Optional(3)], [nil, Optional(4), Optional(5), Optional(6)]]
    
    

     

    어... 네 아무런 변화가 없습니다. 그렇다면 compactMap은 2차원 이상에서는 아무 역할을 못하는 걸까요??

    아닙니다!! compactMap의 역할은 non-nil 한 배열을 리턴해주는거죠?? 따라서 위 예의 a: [[Int?]] 배열에는 nil값은 없고 [Int?] 원소들만 있는 상태입니다. nil값이 없으니 compactMap이 할 수 있는 일은 없겠죠?

    다음 예제를 볼까요?

    let a = [[1, 2, 3], [nil, 4, 5, 6], nil]
    
    let flatMapTest = a.compactMap {
        $0
    }
    
    print(flatMapTest) // [[Optional(1), Optional(2), Optional(3)], [nil, Optional(4), Optional(5), Optional(6)]]
    
    

     

    네 이번에야 말로 compactMap이 할 일이 생겼네요. nil 값을 제거해서 제 역할을 다한 모습을 볼 수 있습니다.

     

    항상 헷갈리던 개념인데 정리하고 나니 별거 아니네요!

    조금이나마 도움이 되셨으면 좋겠습니다. :)

     

     

    'iOS' 카테고리의 다른 글

    iOS) Storyboard 없이 개발하기2 (iOS13 개정판)  (0) 2020.02.10
    UIBeizerPath  (2) 2020.01.09
    Textfield touchUpInside not working  (0) 2019.12.27
    CAGradient location 정복하기  (1) 2019.12.17
    Floating button 만들기 in ScrollView  (4) 2019.12.10

    댓글

Designed by Tistory.