[英]Swift - find object in array of enums with associated values
I have this enum:我有这个枚举:
enum Animal {
case cat(CatModel)
case dog(DogModel)
}
And an array of animals:还有一系列动物:
var animals: [Animal]
I need to find a Cat object in this array by a property that Dog doesn't have.我需要通过 Dog 没有的属性在此数组中找到 Cat object。 litterBoxId
for example.例如litterBoxId
。
let cat = animals.first(where: {$0.litterBoxId == 7})
This of course has an error:这当然有一个错误:
Value of type 'MyViewController.Animal' has no member 'litterBoxId'
How can I accomplish this?我怎样才能做到这一点? I also tried我也试过
($0 as CatModel).litterBoxId
This probably isn't a good use of enums, but here is how it could work:这可能不是对枚举的良好使用,但它是如何工作的:
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 })
You would be much better off using a protocol:使用协议会更好:
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 })
You can use pattern matching to accomplish this with 2 ways.您可以通过 2 种方式使用模式匹配来完成此操作。
Using switch:使用开关:
let cat = animals.first(where: {
switch $0 {
case .cat(let catModel) where catModel.litterBoxId == 7:
return true
default:
return false
}
})
or if:或者如果:
let cat = animals.first(where: {
if case .cat(let catModel) = $0, catModel.litterBoxId == 7 {
return true
}
return false
})
Update : As @Alexander-ReinstateMonica mentioned in his commnet, it would be more appropriate to hide this logic behind a function like this:更新:正如@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
}
}
}
and then your code will be much cleaner:然后你的代码会更干净:
let cat = animals.first(where: { $0.matches(litterboxID: 7) })
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.