如何使用 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
}

你得到一个错误。

解释

这是因为 userNamefullName 被定义为可选项。在这种情况下,您不能简单地编写 [=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 使用像 0empty 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 值设置为 userNamefullName(这是您的应用程序,只有您可以回答这个问题),那么只需管理这种可能性

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
}