繁体   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