多重过滤的布尔语句 Swift
Boolean statement for multiple filtering Swift
我目前正在 Swift 4.2 中创建一个应用程序,我想要一个允许用户 select 多个过滤器的过滤功能。
我有一组当前 selected 过滤器,例如 ["Low"、"Unread"]。我还有一个要过滤的 object 数组。但我正在努力弄清楚如何将多个过滤器应用于此数组,特别是由于 object 具有 children,而后者又具有过滤的属性。例如 object 数组包含 bulletin.importance.name,这是 属性 将检查 "Low"。
以下代码是一个布尔返回函数,它将获取要在公告数组 objects:
上使用的过滤器
return (bulletin.bulletinVersion?.issued == true) && (scopes.contains("All") || (scopes.contains((bulletin.bulletinVersion?.bulletin?.importance?.name)!) ||
(!scopes.contains(where: {[=11=] == "Low" || [=11=] == "Normal" || [=11=] == "High"}))) && (scopes.contains(bulletin.read(i: bulletin.firstReadDate)) ||
(!scopes.contains(where: {[=11=] == "Unread"}))) &&
(scopes.contains(bulletin.signed(i: bulletin.signDate)) && bulletin.bulletinVersion?.bulletin?.requiresSignature == true) && scopes.contains(bulletin.favourited(i: bulletin.favourite)))
这是我目前尝试的布尔检查。我希望它很难设置,所以如果用户 selects "High" 和 "Unread" 它只会显示匹配这两个过滤器的 objects。
此处调用该函数,获取过滤器并过滤所有公告的数组,这些公告应根据过滤器显示在其中:
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 谓词将仅显示与所有过滤器匹配的公告。
因此,未读 + 未签名 + 高将显示所有未读和未签名的高重要性公告。
我不确定你在问什么,但你可以。首先,您可以格式化您的代码以使其更具可读性......我知道多个 return 点被认为是不好的,但潮流似乎正在转向这一点。我会按照重要性的顺序挑选案例,return 你能找到的任何明确的布尔值。例如(未经测试的代码,因为我不知道公告和范围是什么):
func foo(bulletin: Bulletin, scopes: Scopes) -> Bool {
if bulletin.bulletinVersion?.issued == true && scopes.contains("All") {
return true
}
if scopes.contains(bulletin.bulletinVersion?.bulletin?.importance?.name)! {
return true
}
if scopes.contains(bulletin.bulletinVersion?.bulletin?.importance?.name)! {
return true
}
if !scopes.contains(where: {[=10=] == "Low" || [=10=] == "Normal" || [=10=] == "High"})
&& (scopes.contains(bulletin.read(i: bulletin.firstReadDate) {
return true
}
if !scopes.contains(where: {[=10=] == "Unread"})
&& scopes.contains(bulletin.signed(i: bulletin.signDate)
&& bulletin.bulletinVersion?.bulletin?.requiresSignature == true
&& scopes.contains(bulletin.favourited(i: bulletin.favourite)) {
return true
}
return false
}
请注意,这些子句中的每一个都会测试是否为真,如果合适的话 returns 它,因此一旦找到真实情况,函数就会 returns 。 tsts 的顺序可能会影响逻辑。
我会考虑创建一个带有公告、范围和return真或假的方法的协议。
protocol Filter {
func test(bulletin: Bulletin, scopes: Scopes) -> Bool
}
然后创建此协议的实现者:
class AFilter: Filter {
func test(bulletin: Bulletin, scopes: Scopes) -> Bool {
if bulletin.bulletinVersion?.issued == true && scopes.contains("All") {
return true
}
return false
}
}
一旦你建立了你可以做的过滤器实例列表(修改以匹配明确的要求):
for filter in filters {
if !filter.test(bulletin: bulletin, scopes: scopes) {
return false
}
}
return true
(奖励:请注意使用此设计模式更改逻辑是多么容易)
我决定将每个过滤器放入字典中,而不是尝试将大量布尔组合放入一个语句中:
public var filters:[String: Any] = ["importance":[],
"unread": false,
"unsigned": false,
"favourite": false]
重要性过滤器将包含一个字符串数组,例如 ["Low"、"Medium"、"High"]。
单击过滤器按钮时,如果过滤器是布尔值或数组中的 appended/removed,过滤器将被切换:
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(([=12=].bulletinVersion?.bulletin?.importance?.name)!)})
}
}
if let unread = filters["unread"] as! Bool?
{
if(unread)
{
filteredBulletins = filteredBulletins.filter({[=12=].firstReadDate == nil})
}
}
if let unsigned = filters["unsigned"] as! Bool?
{
if(unsigned)
{
filteredBulletins = filteredBulletins.filter({[=12=].bulletinVersion?.bulletin?.requiresSignature == true && [=12=].signDate == nil})
}
}
if let favourite = filters["favourite"] as! Bool?
{
if(favourite)
{
filteredBulletins = filteredBulletins.filter({[=12=].favourite == true})
}
}
字典中包含和删除过滤器确实使我的需求更加明确。试图创建一个布尔语句的怪物将是无限困难的,以使其足够动态以匹配每个可能的过滤器组合(我什至不确定它是否可能)。
但是感谢所有评论提供替代解决方案的人,你们真的帮助我跳出框框思考! :)
我目前正在 Swift 4.2 中创建一个应用程序,我想要一个允许用户 select 多个过滤器的过滤功能。
我有一组当前 selected 过滤器,例如 ["Low"、"Unread"]。我还有一个要过滤的 object 数组。但我正在努力弄清楚如何将多个过滤器应用于此数组,特别是由于 object 具有 children,而后者又具有过滤的属性。例如 object 数组包含 bulletin.importance.name,这是 属性 将检查 "Low"。
以下代码是一个布尔返回函数,它将获取要在公告数组 objects:
上使用的过滤器return (bulletin.bulletinVersion?.issued == true) && (scopes.contains("All") || (scopes.contains((bulletin.bulletinVersion?.bulletin?.importance?.name)!) ||
(!scopes.contains(where: {[=11=] == "Low" || [=11=] == "Normal" || [=11=] == "High"}))) && (scopes.contains(bulletin.read(i: bulletin.firstReadDate)) ||
(!scopes.contains(where: {[=11=] == "Unread"}))) &&
(scopes.contains(bulletin.signed(i: bulletin.signDate)) && bulletin.bulletinVersion?.bulletin?.requiresSignature == true) && scopes.contains(bulletin.favourited(i: bulletin.favourite)))
这是我目前尝试的布尔检查。我希望它很难设置,所以如果用户 selects "High" 和 "Unread" 它只会显示匹配这两个过滤器的 objects。
此处调用该函数,获取过滤器并过滤所有公告的数组,这些公告应根据过滤器显示在其中:
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 谓词将仅显示与所有过滤器匹配的公告。 因此,未读 + 未签名 + 高将显示所有未读和未签名的高重要性公告。
我不确定你在问什么,但你可以。首先,您可以格式化您的代码以使其更具可读性......我知道多个 return 点被认为是不好的,但潮流似乎正在转向这一点。我会按照重要性的顺序挑选案例,return 你能找到的任何明确的布尔值。例如(未经测试的代码,因为我不知道公告和范围是什么):
func foo(bulletin: Bulletin, scopes: Scopes) -> Bool {
if bulletin.bulletinVersion?.issued == true && scopes.contains("All") {
return true
}
if scopes.contains(bulletin.bulletinVersion?.bulletin?.importance?.name)! {
return true
}
if scopes.contains(bulletin.bulletinVersion?.bulletin?.importance?.name)! {
return true
}
if !scopes.contains(where: {[=10=] == "Low" || [=10=] == "Normal" || [=10=] == "High"})
&& (scopes.contains(bulletin.read(i: bulletin.firstReadDate) {
return true
}
if !scopes.contains(where: {[=10=] == "Unread"})
&& scopes.contains(bulletin.signed(i: bulletin.signDate)
&& bulletin.bulletinVersion?.bulletin?.requiresSignature == true
&& scopes.contains(bulletin.favourited(i: bulletin.favourite)) {
return true
}
return false
}
请注意,这些子句中的每一个都会测试是否为真,如果合适的话 returns 它,因此一旦找到真实情况,函数就会 returns 。 tsts 的顺序可能会影响逻辑。
我会考虑创建一个带有公告、范围和return真或假的方法的协议。
protocol Filter {
func test(bulletin: Bulletin, scopes: Scopes) -> Bool
}
然后创建此协议的实现者:
class AFilter: Filter {
func test(bulletin: Bulletin, scopes: Scopes) -> Bool {
if bulletin.bulletinVersion?.issued == true && scopes.contains("All") {
return true
}
return false
}
}
一旦你建立了你可以做的过滤器实例列表(修改以匹配明确的要求):
for filter in filters {
if !filter.test(bulletin: bulletin, scopes: scopes) {
return false
}
}
return true
(奖励:请注意使用此设计模式更改逻辑是多么容易)
我决定将每个过滤器放入字典中,而不是尝试将大量布尔组合放入一个语句中:
public var filters:[String: Any] = ["importance":[],
"unread": false,
"unsigned": false,
"favourite": false]
重要性过滤器将包含一个字符串数组,例如 ["Low"、"Medium"、"High"]。
单击过滤器按钮时,如果过滤器是布尔值或数组中的 appended/removed,过滤器将被切换:
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(([=12=].bulletinVersion?.bulletin?.importance?.name)!)})
}
}
if let unread = filters["unread"] as! Bool?
{
if(unread)
{
filteredBulletins = filteredBulletins.filter({[=12=].firstReadDate == nil})
}
}
if let unsigned = filters["unsigned"] as! Bool?
{
if(unsigned)
{
filteredBulletins = filteredBulletins.filter({[=12=].bulletinVersion?.bulletin?.requiresSignature == true && [=12=].signDate == nil})
}
}
if let favourite = filters["favourite"] as! Bool?
{
if(favourite)
{
filteredBulletins = filteredBulletins.filter({[=12=].favourite == true})
}
}
字典中包含和删除过滤器确实使我的需求更加明确。试图创建一个布尔语句的怪物将是无限困难的,以使其足够动态以匹配每个可能的过滤器组合(我什至不确定它是否可能)。
但是感谢所有评论提供替代解决方案的人,你们真的帮助我跳出框框思考! :)