簡體   English   中英

Swift - 在具有關聯值的枚舉數組中查找 object

[英]Swift - find object in array of enums with associated values

我有這個枚舉:

enum Animal {       
    case cat(CatModel)
    case dog(DogModel)
}

還有一系列動物:

var animals: [Animal]

我需要通過 Dog 沒有的屬性在此數組中找到 Cat object。 例如litterBoxId

let cat = animals.first(where: {$0.litterBoxId == 7})

這當然有一個錯誤:

Value of type 'MyViewController.Animal' has no member 'litterBoxId'

我怎樣才能做到這一點? 我也試過

($0 as CatModel).litterBoxId

這可能不是對枚舉的良好使用,但它是如何工作的:

struct CatModel {
    let litterBoxID: Int
}

struct DogModel {
    let litterBoxID: Int
}

enum Animal {       
    case cat(CatModel)
    case dog(DogModel)
    
    var litterBoxId: Int {
        switch self {
        case .cat(let cat): return cat.litterBoxID
        case .dog(let dog): return dog.litterBoxID
        }
    }
}

var animals: [Animal] = []
let cat = animals.first(where: { $0.litterBoxId == 7 })

使用協議會更好:

struct CatModel: Animal {
    let litterBoxID: Int
}

struct DogModel: Animal {
    let litterBoxID: Int
}

protocol Animal {
    var litterBoxID: Int { get }
}

var animals: [Animal] = []
let cat = animals.first(where: { $0.litterBoxID == 7 })

您可以通過 2 種方式使用模式匹配來完成此操作。

使用開關:

let cat = animals.first(where: {
    switch $0 {
    case .cat(let catModel) where catModel.litterBoxId == 7:
        return true
    default:
        return false
    }
})

或者如果:

let cat = animals.first(where: {
    if case .cat(let catModel) = $0, catModel.litterBoxId == 7 {
        return true
    }
    return false
})

更新:正如@Alexander-ReinstateMonica 在他的 commnet 中提到的,將這個邏輯隱藏在 function 后面會更合適,如下所示:

extension Animal {
    func matches(litterboxID: Int) -> Bool {
        switch self {
        case .cat(let catModel) where catModel.litterBoxId == 7:
            return true
        default:
            return false
        }
    }
}

然后你的代碼會更干凈:

let cat = animals.first(where: { $0.matches(litterboxID: 7) })

暫無
暫無

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

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