簡體   English   中英

使用關聯值映射swift枚舉

[英]Mapping swift enum with associated values

假設我們有一個帶有相關值類型的枚舉。 在下面的示例中,兩個值類型是包含圖像的簡單對象和要共享的URL。

enum Content {
  case Image(ShareableImage)
  case Video(ShareableVideo)
}

現在讓我們來看一系列視頻和圖像案例。

let media: [Content] = [*a lot of enum cases inside here*]  

到目前為止,上面的所有代碼都無法在代碼庫中以任何方式進行更改,我需要使用它。


這開始我的問題:

讓我們用媒體過濾數組,只對圖像情況進行過濾

    let imageOnlyCases: [Content] = media.filter { item -> Bool in

        switch item {
        case .Image: return true
        default: return false
        }
    }

下一步,我想從枚舉數組獲取其關聯值的數組

[Content] -> [ShareableImage] by using map.

所以我這樣做

    let shareablemages = imageOnlyCases.map { imageCase -> ShareableImage in

        switch imageCase {

        case .Image(let image): return image
        default: return  WHAT TO DO HERE?
        }
    }

你看,我有一個返回類型的問題..我知道枚舉案例都是.Image ..我想要一個簡單的地圖。 但快速的語法並沒有幫助我。

有任何想法嗎?

你可以返回image的情況下.Image ,和nil否則,內.flatMap操作(“過濾”出nil條目):

/* Example */
enum Foo {
    case Bar(Int)
    case Baz(Int)
}

let foo: [Foo] = [.Bar(1), .Bar(9),. Baz(3), .Bar(39), .Baz(5)]

/* 1. using 'switch' */
let barOnlyValues: [Int] = foo.flatMap {
    switch $0 {
    case .Bar(let val): return val
    case _: return nil
    }}

/* 2. alternatively, as pointed out in MartinR:s answer; 
      as you're only looking for a single case, the alternative
      'if case let' clause could be preferred over 'switch':     */
let barOnlyValuesAlt: [Int] = foo.flatMap {
    if case let .Bar(val) = $0 { return val }
    else { return nil }}                               

print(barOnlyValues) // [1, 9, 39]

應用於您的用例:請注意,您無需執行過濾來創建imageOnlyCases數組,因為您可以直接在media數組上應用上述內容:

/* 1. using switch */
let shareableImages : [ShareableImage] = media.flatMap {
    switch $0 {
    case .Image(let image): return image
    case _: return nil
    }}

/* 2. 'if case let' alternative, as per MartinR:s suggestion */
let shareableImagesAlt : [ShareableImage] = media.flatMap {
    if case let .Image(image) = $0 { return image }
    else { return nil }}

免責聲明:我無法在實踐中驗證您的具體用例,因為我無權訪問ShareableImage類/結構。

(感謝@MartinR的建議,即.map{ ... }.flatMap{ ... }可以簡化為.flatMap{ ... } )。

如果它是保證 ,只有.Image可發生情況,那么你可以調用fatalError()在所有其他情況下:

let shareableImages = imageOnlyCases.map { imageCase -> ShareableImage in

    if case let .Image(image) = imageCase {
        return image
    } else {
        fatalError("Unexpected content")
    }
}

fatalError()導致程序立即終止。 它僅適用於“無法發生”的情況,即發現編程錯誤。

它滿足編譯器,因為該函數標記為@noreturn

如果你不能保證,那么使用另一個答案中建議的flatMap()

另請注意,如果使用模式而不是switch/case ,則可以使用if case switch/case

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM