gpt4 book ai didi

swift - 在 Swift 中过滤具有多个条件和类型的对象数组

转载 作者:可可西里 更新时间:2023-11-01 01:22:21 25 4
gpt4 key购买 nike

我正尝试在我的应用程序中进行一些复杂的过滤,但我已经到了不知道下一步该做什么的地步。我的数据由一组字典组成,其中每个字典中的值可以是 StringInt[String]

let person1: [String : Any] = ["first_name" : "John",
"last_name" : "Smith",
"age" : 21,
"skills" : ["C#", "Java", "Swift"]]
let person2: [String : Any] = ["first_name" : "Kim",
"last_name" : "Smith",
"age" : 28,
"skills" : ["Java", "Swift"]]
let person3: [String : Any] = ["first_name" : "Kate",
"last_name" : "Bell",
"age" : 24,
"skills" : ["C#"]]


var people = [person1, person2, person3]

我让用户选择如何过滤这些数据并创建一个过滤条件字典。这个字典可以有任意数量的键和值。

let filters: [String : [Any]] = ["age" : [28, 24],
"skills" : ["Java", "Swift"]]

在这个例子中,我想展示 年龄 28 或 24 岁并且拥有 Java 或 Swift 的技能 的人,即 person2

这是我目前所拥有的,但它只适用于 Int 值:

for (key, values) in filters {
var filteredItems = people.filter {
var match = false
for filterValue in values {
if $0[key] as! Int == filterValue as! Int {
match = true
break
}
else {
match = false
}
}
return match
}
people = filteredItems
}

最佳答案

这是我将如何做到这一点:

struct Person {
let firstName: String
let lastName: String
let age: Int
let skills: [String]

enum Filter {
enum FilterType<T: Hashable> {
case one(of: [T])
case all(of: [T])

// Match against a property that's a single value
func matches(_ value: T) -> Bool {
switch self {
case .one(let filterValues): return filterValues.contains(value)
case .all(let filterValues): return filterValues.count == 1 && filterValues[0] == value
}
}

// Match against a property that's a list of values
func matches(_ values: [T]) -> Bool {
switch self {
case .one(let filterValues): return !Set(filterValues).intersection(values).isEmpty
case .all(let filterValues): return Set(filterValues).isSuperset(of: values)
}
}
}

case age(is: FilterType<Int>)
case skills(is: FilterType<String>)

func matches(_ p: Person) -> Bool {
switch self {
case .age(let filterValues): return filterValues.matches(p.age)
case .skills(let filterValues): return filterValues.matches(p.skills)
}
}
}
}

extension Array where Element == Person.Filter {
func atLeastOneMatch(_ p: Person) -> Bool {
self.contains(where: { $0.matches(p) })
}

func matchesAll(_ p: Person) -> Bool {
self.allSatisfy { $0.matches(p) }
}
}

let people = [
Person(
firstName: "John",
lastName : "Smith",
age: 21,
skills: ["C#", "Java", "Swift"]
),
Person(
firstName: "Kim",
lastName : "Smith",
age: 28,
skills: ["Java", "Swift"]
),
Person(
firstName: "Kate",
lastName: "Bell",
age: 24,
skills: ["C#"]
),
]


let filters: [Person.Filter] = [
.age(is: .one(of: [28, 24])),
.skills(is: .one(of: ["Java", "Swift"])),
]

let peopleWhoMatchAllFilters = people.filter(filters.matchesAll)
print(peopleWhoMatchAllFilters)

let peopleWhoMatchAtLeastOneFilter = people.filter(filters.atLeastOneMatch)
print(peopleWhoMatchAtLeastOneFilter)

我已经扩展了过滤功能,以便能够指定过滤器的所有值是否应该匹配(例如,一个人必须知道 Java 和 Swift 和 C#)或至少一个(例如,一个人必须至少知道 Java 或 swift 或 C#)

关于swift - 在 Swift 中过滤具有多个条件和类型的对象数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43286789/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com