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

克里斯

我正在尝试在我的应用程序中进行一些复杂的过滤,但是到了我不知道下一步该怎么做的地步。字典的阵列,其中在每一个字典的值可以是我的数据consistes 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"]]

在此示例中,我想显示age28岁或24岁且具有skillsJava或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 AND Swift AND C#)或至少一个(例如,一个人必须知道至少Java或Swift或C# )

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

正确过滤具有多个条件的对象数组和一个数组

在python中过滤具有多个条件的对象的列表

在多个条件下过滤具有多个属性的对象数组

为什么过滤具有多个条件的对象数组会返回一个空数组?

在Swift中具有引用和类型成员的数组相等

如何在具有多个条件数组的javascript中链接多个过滤器函数

过滤具有多个属性的多个数组对象

在具有多个对象的数组中应用数组过滤器时出错

按条件和对象属性类型过滤数组

如何过滤具有多个条件的嵌套数组?

无法使用具有多个条件语句的过滤器从数组中删除元音

Swift中的if语句具有多个条件

在javascript中基于具有多个数组的另一个对象的过滤来过滤数组

在 swift 4 中从数组中过滤/ flatMap 出具有任何 nil 值的对象

根据javascript中的条件在数组中插入具有相同键值的多个对象

MongoDB - 使用多个过滤条件更新数组对象中的字段

如何使用数组中的多个条件过滤对象?

在Swift中的数组中填充具有多个节和多个字典的TableView

Swift ObjectMapper映射具有多种类型的值的数组-数字和复杂对象混合

从具有多个条件的 Map 中过滤出结果

React中具有多个条件的复杂结果过滤

过滤对象的快速数组以删除在其一个或多个属性中具有相同值的对象

从数组中过滤多个对象

在 Python 中过滤具有条件的对象列表

在JavaScript中,如何过滤具有动态条件的数组?

从javascript数组中过滤具有特定属性的对象

在JavaScript中,当使用.map()函数迭代具有原始类型和对象的数组时

在多个列中具有多个条件和OR逻辑的SUMIFS

打字稿:条件类型的过滤器数组并具有正确的返回类型