我正在为以下问题寻找一个很好的快速解决方案:
假设我们有 2 个像这样的结构:
struct Person {
let name: String
let age: Int
let skills: Skills
init(name: String, age: Int, skills: Skills) {
self.name = name
self.age = age
self.skills = skills
}
}
struct Skills {
let canUseBow: Bool
let canUseSword: Bool
let canUseShield: Bool
init(canUseBow: Bool, canUseSword: Bool, canUseShield: Bool) {
self.canUseBow = canUseBow
self.canUseSword = canUseSword
self.canUseShield = canUseShield
}
}
现在假设我有一个 Person 数组,其中每个人显然都有自己的技能,其中相应的值可以为真或为假。
假设我想要另一个具有技能 canUseBow
为 true 的人的数组,因此必须将技能设置为 true ,我将如何过滤掉没有 canUseBow
的人设置为真?
我考虑的方向是:
filteredPersons = persons.filter {
$0.skills
}
但是这样就需要我在技能之后选择一些东西
$0.skills.canUseBow
这似乎不是未来的证明,假设我想要添加更多技能,而不是再次更改过滤器方法。有没有更好的方法来解决这个问题?
答案 0 :(得分:3)
您可以使用 OptionSet
尝试此操作,它可以在一个简单的 Int
存储中为您保存所有这些标志。
import Foundation
struct Person {
let name: String
let age: Int
let skills: Skills
init(name: String, age: Int, skills: Skills) {
self.name = name
self.age = age
self.skills = skills
}
}
struct Skills: OptionSet {
let rawValue: Int
init(rawValue: Int) {
self.rawValue = rawValue
}
static let canUseBow = Skills(rawValue: 1 << 0)
static let canUseSword = Skills(rawValue: 1 << 1)
static let canUseShield = Skills(rawValue: 1 << 2)
init(json: [String: Bool]) {
var skills = Skills(rawValue: 0)
if let canUseBow = json["can_use_bow"], canUseBow {
skills.insert(.canUseBow)
}
if let canUseSword = json["can_use_sword"], canUseSword {
skills.insert(.canUseSword)
}
if let canUseShield = json["can_use_shield"], canUseShield {
skills.insert(.canUseShield)
}
self = skills
}
}
Skills
?let skills = Skills(json: [
"can_use_bow" : true,
"can_use_sword" : true,
"can_use_shield" : false,
])
let targetSkills: Skills = [.canUseBow, .canUseSword]
let persons: [Person] = []
let filteredPersons = persons.filter {
targetSkills.isSubset(of: $0.skills)
}