如何使用 OR 子句过滤 Swift 中的数组
How to use an OR clause to filter an array in Swift
我正在尝试通过匹配用户名或全名来过滤 Swift 中的一组对象。
filteredRegUserArray = regUserArray.filter {
[=11=].userName.lowercaseString.hasPrefix(lowercasePrefix) ||
[=11=].fullName.lowercaseString.hasPrefix(lowercasePrefix)}
您的场景
所以看起来你有我这样的结构(或class)
struct User {
let userName: String?
let fullName: String?
}
您还有一组用户
let users = [User]()
你的问题
现在,当您尝试过滤数组时
let lowercasePrefix = "abc"
let filtered = users.filter {
[=12=].userName.lowercaseString.hasPrefix(lowercasePrefix) == true
|| [=12=].fullName.lowercaseString.hasPrefix(lowercasePrefix) == true
}
你得到一个错误。
解释
这是因为 userName
和 fullName
被定义为可选项。在这种情况下,您不能简单地编写 [=18=].userName.lowercaseString
,因为编译器无法确定 userName
中是否存在值。它会阻止您阅读 nil
值上的 lowercaseString
属性 以防止崩溃。
您的(错误)解决方案
您似乎解决了以这种方式更改结构的问题
struct User {
var userName: String = " "
var fullName: String = " "
init(userName:String, fullName:String) {
self.userName = userName
self.fullName = fullName
}
}
让我说这很丑陋。这也是 Swift 从一开始就试图与之抗争的东西。这个想法是你应该 NEVER 使用像 0
或 empty String
这样的值(或者奇怪的是像这种情况下的 blank space
)来指示没有价值。 缺少值必须用nil
表示。
因此,尽管此解决方案确实可以编译,但从设计的角度来看它非常糟糕,并且可能会在将来给您带来一些问题。
解决方案 1
从不接受 nil
User
属性的值
struct User {
let userName: String
let fullName: String
}
let users = [User]()
let lowercasePrefix = "abc"
let filtered = users.filter {
[=14=].userName.lowercaseString.hasPrefix(lowercasePrefix) == true
|| [=14=].fullName.lowercaseString.hasPrefix(lowercasePrefix) == true
}
解决方案 2
如果用户可以将 nil
值设置为 userName
或 fullName
(这是您的应用程序,只有您可以回答这个问题),那么只需管理这种可能性
struct User {
let userName: String?
let fullName: String?
}
let users = [User]()
let lowercasePrefix = "abc"
let filtered = users.filter {
[=15=].userName?.lowercaseString.hasPrefix(lowercasePrefix) == true
|| [=15=].fullName?.lowercaseString.hasPrefix(lowercasePrefix) == true
}
我正在尝试通过匹配用户名或全名来过滤 Swift 中的一组对象。
filteredRegUserArray = regUserArray.filter {
[=11=].userName.lowercaseString.hasPrefix(lowercasePrefix) ||
[=11=].fullName.lowercaseString.hasPrefix(lowercasePrefix)}
您的场景
所以看起来你有我这样的结构(或class)
struct User {
let userName: String?
let fullName: String?
}
您还有一组用户
let users = [User]()
你的问题
现在,当您尝试过滤数组时
let lowercasePrefix = "abc"
let filtered = users.filter {
[=12=].userName.lowercaseString.hasPrefix(lowercasePrefix) == true
|| [=12=].fullName.lowercaseString.hasPrefix(lowercasePrefix) == true
}
你得到一个错误。
解释
这是因为 userName
和 fullName
被定义为可选项。在这种情况下,您不能简单地编写 [=18=].userName.lowercaseString
,因为编译器无法确定 userName
中是否存在值。它会阻止您阅读 nil
值上的 lowercaseString
属性 以防止崩溃。
您的(错误)解决方案
您似乎解决了以这种方式更改结构的问题
struct User {
var userName: String = " "
var fullName: String = " "
init(userName:String, fullName:String) {
self.userName = userName
self.fullName = fullName
}
}
让我说这很丑陋。这也是 Swift 从一开始就试图与之抗争的东西。这个想法是你应该 NEVER 使用像 0
或 empty String
这样的值(或者奇怪的是像这种情况下的 blank space
)来指示没有价值。 缺少值必须用nil
表示。
因此,尽管此解决方案确实可以编译,但从设计的角度来看它非常糟糕,并且可能会在将来给您带来一些问题。
解决方案 1
从不接受 nil
User
struct User {
let userName: String
let fullName: String
}
let users = [User]()
let lowercasePrefix = "abc"
let filtered = users.filter {
[=14=].userName.lowercaseString.hasPrefix(lowercasePrefix) == true
|| [=14=].fullName.lowercaseString.hasPrefix(lowercasePrefix) == true
}
解决方案 2
如果用户可以将 nil
值设置为 userName
或 fullName
(这是您的应用程序,只有您可以回答这个问题),那么只需管理这种可能性
struct User {
let userName: String?
let fullName: String?
}
let users = [User]()
let lowercasePrefix = "abc"
let filtered = users.filter {
[=15=].userName?.lowercaseString.hasPrefix(lowercasePrefix) == true
|| [=15=].fullName?.lowercaseString.hasPrefix(lowercasePrefix) == true
}