ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • FlatMap, CompactMap
    Swift/Tips & Tricks 2022. 4. 8. 16:02

    Swift 를 쓰다보면 (다른 언어들도 마찬가지겠지만) Array 를 다룰 때 flatMap, compactMap 에 대해 다루게 된다.

    먼저 정의부터 살펴보자.

    compactMap

    Summary

    Sequence 의 각 element 에 주어진 transform 을 시행했을 때 nil 이 아닌 결과들로 이루어진 array 

    Discussion

    transformation 이 optional value 를 생성시킬 수 있을 때, optional 이 아닌 값들의 array 를 원할 때 사용하면 된다. 

    복잡도: O(m+n), n: sequence 의 크기, m: 결과의 크기

    Example

    예시에서 .map 은 optional 을 생성하고 nil 값을 생성할 수도 있지만, compactMap 을 사용할 경우 이때에는 결과에서 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]

    Returns

    Sequence 의 각 element 에 대해서 transform 을 시행했을 때 생성되는 값들 중 nil 이 아닌 값들의 Array

     

     

     

     

     

     

     

    flatMap

    Summary

    Sequence 의 각 element 에 대해 transformation 이 시행된 각 결과를 이어 붙인 Array 를 반환한다. 

    (Transformation 의 결과가 Observable 일 때, 각 Observable의 Element 를 이어 붙인 Observable 을 Return한다. )

    (map 과의 차이를 분명하게 알아야함.  (그래서 위에 Map 의 diagram 첨부함) 
    (map 을 통해 Observable<String> 이 나오는 sequence 에서, map 대신 flatMap 이 들어가면 String 이 나옴.. )

     

    Discussion

    Transformation 이  각 element 에 대해 적용된 결과로 sequence 또는 collection 을 생성할 때, single-level collection 을 얻기 위해 사용. (map 의 경우 sequence or collection 들을 가진 collection 을 반환) 

     

     s.flatMap(transform) 와 Array(s.map(transform).join()) 은 같은 결과를 낸다. 

    복잡도: O(m+n), n: sequence 의 크기, m: 결과의 크기

     

    Example
    아래 예시에서 보면, map 의 경우 여러 Arrays 를 반환하지만, flat 시키면 이것들을 '평평하게 한' 결과를 얻을 수 있다. 

    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]

     

    Returns

    'Flatten' Array

     

        [1],[2, 2],[3, 3, 3],[4, 4, 4, 4]
     [                                    ]
    
    
        [1, 2, 2, 3, 3, 3, 4, 4, 4, 4]

     

     

     

     

     

     

    struct Store {
        let name: String
        let electronicHardware: [String]
    }
    
    
    
    // find all of the electronic items sold in the area
    
    //let target = Store(name: "Target", electr)
    let target = Store(name: "Target", electronicHardware: [
        "iPhone", "iPad", "Flatscreen TVs"
    ])
    
    
    let bestBuys = Store(name: "Best Buy", electronicHardware: [
        "Laptops", "Big Friges"]
    )
    
    let bedBathAndBeyond = Store(name: "Bed Bath & Beyond", electronicHardware:[])
    
    let items = target.electronicHardware + bestBuys.electronicHardware + bedBathAndBeyond.electronicHardware
    // ["iPhone", "iPad", "Flatscreen TVs", "Laptops", "Big Friges"]
    let items2 = [target, bestBuys, bedBathAndBeyond].map { $0.electronicHardware}
    //[["iPhone", "iPad", "Flatscreen TVs"], ["Laptops", "Big Friges"], []]
    let items3 = [target, bestBuys, bedBathAndBeyond].flatMap { $0.electronicHardware}
    //["iPhone", "iPad", "Flatscreen TVs", "Laptops", "Big Friges"]
    
    struct Store2 {
        let name: String
        let electronicHardware: [String]?
    }
    
    let target2 = Store2(name: "Target", electronicHardware: [
        "iPhone", "iPad", "Flatscreen TVs"
    ])
    
    let bestBuys2 = Store2(name: "Best Buy", electronicHardware: [
        "Laptops", "Big Friges"]
    )
    
    let bedBathAndBeyond2 = Store2(name: "Bed Bath & Beyond", electronicHardware:nil)
    
    
    //let itemss = target2.electronicHardware! + bestBuys2.electronicHardware! + bedBathAndBeyond2.electronicHardware!
    
    let itemss2 = [target2, bestBuys2, bedBathAndBeyond2].map { $0.electronicHardware}
    //[["iPhone", "iPad", "Flatscreen TVs"], ["Laptops", "Big Friges"], nil]
    let itemss3 = [target2, bestBuys2, bedBathAndBeyond2].compactMap { $0.electronicHardware}.flatMap{$0}
    // ["iPhone", "iPad", "Flatscreen TVs", "Laptops", "Big Friges"]
    
    //'flatMap' is deprecated: Please use compactMap(_:) for the case where closure returns an optional value
Designed by Tistory.