ios - 多重过滤 Swift 的 boolean 语句

标签 ios swift filter boolean predicate

我目前正在使用 Swift 4.2 创建一个应用程序,我想要一个允许用户选择多个过滤器的过滤功能。

我有一组当前选择的过滤器,例如 ["Low", "Unread"]。我还有一组被过滤的对象。但我正在努力弄清楚如何对这个数组应用多个过滤器,特别是因为对象有 child ,而 child 又有被过滤的属性。例如,对象数组包含 bulletin.importance.name,这是检查“低”的属性。

以下代码是一个返回 boolean 值的函数,它将获取要在公告对象数组上使用的过滤器:

return (bulletin.bulletinVersion?.issued == true) && (scopes.contains("All") || (scopes.contains((bulletin.bulletinVersion?.bulletin?.importance?.name)!) ||
        (!scopes.contains(where: {$0 == "Low" || $0 == "Normal" || $0 == "High"}))) && (scopes.contains(bulletin.read(i: bulletin.firstReadDate)) ||
            (!scopes.contains(where: {$0 == "Unread"}))) &&
            (scopes.contains(bulletin.signed(i: bulletin.signDate)) && bulletin.bulletinVersion?.bulletin?.requiresSignature == true) && scopes.contains(bulletin.favourited(i: bulletin.favourite)))

这是我目前对 boolean 检查的尝试。我希望它很难设置,这样如果用户选择“高”和“未读”,它只会显示与这两个过滤器都匹配的对象。

函数在此处被调用,获取过滤器并过滤所有公告的数组,这些公告应根据过滤器显示在其中:

currentBulletinArray = bulletinArray.filter({bulletin -> Bool in
    let doesCategoryMatch = getScopeFilters(issued: true, scopes: scope, bulletin: bulletin, signature: true)

    if searchBarIsEmpty(){
        return doesCategoryMatch
    } else {
        return doesCategoryMatch && (bulletin.bulletinVersion?.bulletin?.name?.lowercased().contains(searchText.lowercased()))!
    }
   })

我希望能够设置任何过滤器组合,其中返回的 .filter 谓词将仅显示与所有过滤器匹配的公告。 因此,未读 + 未签名 + 高将显示所有未读和未签名的高重要性公告。

最佳答案

我决定将每个过滤器放入一个字典中,而不是试图将大量的 boolean 组合放入一个语句中:

 public var filters:[String: Any] = ["importance":[],
                             "unread": false,
                             "unsigned": false,
                             "favourite": false]

重要性过滤器将包含一个字符串数组,例如 ["Low", "Medium", "High"]。

单击过滤器按钮时,如果过滤器是 boolean 值或从数组中添加/删除,过滤器将被切换:

if(!importanceToAdd.isEmpty){
            filters["importance"] = importanceToAdd
        }
        if(cell.filterTitleLabel.text == "Unread")
        {
            filters["unread"] = true
        }
        if(cell.filterTitleLabel.text == "Unsigned")
        {
            filters["unsigned"] = true
        }
        if(cell.filterTitleLabel.text == "Favourites")
        {
            filters["favourite"] = true
        }

然后,在一个单独的函数中,我检查过滤器是否已独立设置。如果是,则按以下每个条件过滤公告数组:

 if let importance = filters["importance"] as! [String]?{
        if(importance.count != 0){
            filteredBulletins = filteredBulletins.filter({importance.contains(($0.bulletinVersion?.bulletin?.importance?.name)!)})
        }
    }

    if let unread = filters["unread"] as! Bool?
    {
        if(unread)
        {
            filteredBulletins = filteredBulletins.filter({$0.firstReadDate == nil})
        }

    }

    if let unsigned = filters["unsigned"] as! Bool?
    {
        if(unsigned)
        {
            filteredBulletins = filteredBulletins.filter({$0.bulletinVersion?.bulletin?.requiresSignature == true && $0.signDate == nil})
        }
    }

    if let favourite = filters["favourite"] as! Bool?
    {
        if(favourite)
        {
            filteredBulletins = filteredBulletins.filter({$0.favourite == true})
        }
    }

字典中包含和删除过滤器确实使我的需求更加明确。试图创建一个 boolean 语句的怪物将是无限困难的,以使其足够动态以匹配每个可能的过滤器组合(我什至不确定它是否可能)。

但感谢所有评论提供替代解决方案的人,你们真的帮助我跳出框框思考! :)

关于ios - 多重过滤 Swift 的 boolean 语句,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52836257/

相关文章:

iphone - 如何在 xcode 中检查 NSArray 和 NSDictionary 中的元素?

iphone - 如何在 iOS 中的图表中显示小图像

ios - Swift:在展开期间 performSegueWithIdentifier 不起作用

ios - 使一个小的 UIImageView 易于被点击

css - 使用过滤器 css 属性会破坏 IE 上的布局

iOS + XMPP - 我可以在 iOS 中实现推送通知 XMPPFramework 吗?

ios - Objective-C 代码的符号剥离仍然以二进制形式留下方法名称等

ios - swift - 在没有虚拟间隔 View 的情况下垂直居中多个 View

javascript - 过滤 ViewModel 存储并实现到 ExtJS 面板的正确方法是什么?

python - python中的列表理解函数