Swift 2 - 连接可选字符串的正确方法?

Jos*_*osa 19 swift

让我们假设我有一个Person命名的类的实例personfirstlast名称特性,这都是可选的字符串.

现在我想要构造一个fullName字符串,其中只包含它们的名字或姓氏(如果那是可用的),或者如果我们同时包含它们,它们的名字和名字在中间有一个空格.

var fullName : String?
if let first = person.first {
    name = first
}
if let last = person.last {
    if name == nil {
        name = last
    } else {
        name! += " " + last
    }
}
Run Code Online (Sandbox Code Playgroud)

要么

var name = ""
if let first = person.first {
    name = first
}
if let last = person.last {
    name = name.characters.count > 0 ? name + " " + last : last
}
Run Code Online (Sandbox Code Playgroud)

我理解选项,但我不能完全围绕"Swift"思考它们并安全地展开处理的方式.我们只是想窝if let吗?是否有更清洁,更"快捷"的方式来做上述事情?Nil合并似乎是合适的,但我想不出如何在这种情况下应用它.我不禁感到我在以过于复杂的方式进行可选的字符串连接.

ois*_*sdk 70

compactMap在这里工作得很好,结合.joined(separator:):

let f: String? = "jo"
let l: String? = "smith"

[f,l] // "jo smith"
  .compactMap { $0 }
  .joined(separator: " ")
Run Code Online (Sandbox Code Playgroud)

它不会在以下之间留出空间nil:

let n: String? = nil

[f,n] // "jo"
  .compactMap { $0 }
  .joined(separator: " ")
Run Code Online (Sandbox Code Playgroud)

  • 如果两者都是零,则它给出一个空字符串,这至少是理智的.非常好! (3认同)

mat*_*att 6

有时简单是最好的:

let first = p.first ?? ""
let last = p.last ?? ""
let both = !first.isEmpty && !last.isEmpty
let full = first + (both ? " " : "") + last
Run Code Online (Sandbox Code Playgroud)

如果没有,first或者last如果存在first但是没有last,如果存在last但是没有first,并且如果存在a first和a ,则这有效last.我想不出任何其他情况.

以下是将该想法合并到计算变量中的惯用语; 作为一个额外的好处,我已经允许fullnil以防万一两个其它名称是nil:

struct Person {
    var first : String?
    var last : String?
    var full : String? {
        if first == nil && last == nil { return nil }
        let fi = p.first ?? ""
        let la = p.last ?? ""
        let both = !fi.isEmpty && !la.isEmpty
        return fi + (both ? " " : "") + la
    }
}
Run Code Online (Sandbox Code Playgroud)


Dav*_*rry 5

在某处,我相信 swift 的书,我遇到了这种模式,从以前你可以在一个单一的时候有多个让如果:

class User {
    var lastName : String?
    var firstName : String?

    var fullName : String {
        switch (firstName, lastName) {
        case (.Some, .Some):
            return firstName! + " " + lastName!

        case (.None, .Some):
            return lastName!

        case (.Some, .None):
            return firstName!

        default:
            return ""
        }
    }

    init(lastName:String?, firstName:String?) {
        self.lastName = lastName
        self.firstName = firstName
    }
}

User(lastName: nil, firstName: "first").fullName        // -> "first"
User(lastName: "last", firstName: nil).fullName         // -> "last"
User(lastName: nil, firstName: nil).fullName            // -> ""
User(lastName: "last", firstName: "first").fullName     // -> "first last"
Run Code Online (Sandbox Code Playgroud)

一个更简短的解决方案,给定 swift 3.0:

var fullName : String {
    return [ firstName, lastName ].flatMap({$0}).joined(separator:" ")
}
Run Code Online (Sandbox Code Playgroud)