我们假设我有一个名为Person
的{{1}}类实例,其person
和first
名称属性都是可选字符串。< / p>
现在我想构建一个last
字符串,其中只包含它们的名字或姓氏(如果它们全部可用),或者如果我们同时包含它们的名字,那么它们的名字和姓氏都是中间的空间。
fullName
或
var fullName : String?
if let first = person.first {
name = first
}
if let last = person.last {
if name == nil {
name = last
} else {
name! += " " + last
}
}
我理解选项,但我不能完全围绕着#Sw;&#34;&#34; Swift&#34;思考它们和处理安全展开的方式。我们应该嵌套var name = ""
if let first = person.first {
name = first
}
if let last = person.last {
name = name.characters.count > 0 ? name + " " + last : last
}
吗?是否有更清洁,更多&#34; Swift&#34;这样做的方式? Nil合并似乎是合适的,但我不能想到如何在这种情况下应用它。我无法帮助,但感觉我是以过于复杂的方式进行可选的字符串连接。
答案 0 :(得分:64)
compactMap
在这里工作得很好,与.joined(separator:)
结合使用:
let f: String? = "jo"
let l: String? = "smith"
[f,l] // "jo smith"
.compactMap { $0 }
.joined(separator: " ")
如果一个是nil
:
let n: String? = nil
[f,n] // "jo"
.compactMap { $0 }
.joined(separator: " ")
答案 1 :(得分:5)
有时简单是最好的:
let first = p.first ?? ""
let last = p.last ?? ""
let both = !first.isEmpty && !last.isEmpty
let full = first + (both ? " " : "") + last
如果没有first
或last
,如果有first
但没有last
,如果有last
但没有{{} {1}},如果同时包含first
和first
。我想不出任何其他情况。
这是将这个想法合并到计算变量中的惯用语;作为额外的好处,我允许last
为full
以防其他名称nil
:
nil
答案 2 :(得分:3)
在某个地方,我相信这本快速的书,我遇到了这种模式,从此之前你可以在一个单独的if中使用多个let:
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"
一个更简洁的解决方案,给出了swift 3.0:
var fullName : String {
return [ firstName, lastName ].flatMap({$0}).joined(separator:" ")
}
答案 3 :(得分:2)
这是另一种方法:
let name =
(person.first != nil && person.last != nil) ?
person.first! + " " + person.last! :
person.first ?? person.last!
答案 4 :(得分:1)
我喜欢oisdk's approach,但如果两者都是nil
,我就不喜欢空字符串。我宁愿拥有nil
。
func add(a a: String?, b: String?, separator: String = " ") -> String? {
let results = [a, b].flatMap {$0}
guard results.count > 0 else { return nil }
return results.joinWithSeparator(separator)
}
答案 5 :(得分:1)
oisdk回答的很棒,但我需要一些与OP原始问题非常具体的内容。
写 Swift 4.x ,我创建了这个扩展,在填充其他字符串(例如文本标签)时效果很好。我还更新了它,以便在需要时包含一个处理数组的函数。
extension String {
static func combine(first: String?, second: String?) -> String {
return [first, second].compactMap{ $0 }.joined(separator: " ")
}
static func combine(strings: [String?]) -> String {
return strings.compactMap { $0 }.joined(separator: " ")
}
}
使用两个可选字符串填充文本标签的示例:
print(String.combine(first: "First", second: "Last")) // "First Last"
print(String.combine(first: "First", second: nil)) // "First"
print(String.combine(first: nil, second: "Last")) // "Last"
如果你有一个可选字符串数组,你可以调用数组函数:
print(String.combine(strings: ["I", "Have", nil, "A", "String", nil, "Here"]))
// "I Have A String Here"
答案 6 :(得分:1)
for swift 4
let name: String? = "Foo"
let surname: String? = "Bar"
let fullname = (name ?? "") + " " + (surname ?? "")
print(fullname)
// Foo Bar
答案 7 :(得分:0)
class cls {
constructor(options) {
Object.assign(this, {
arr: [],
}, options);
this.arr[0] = 1; // <- IDE thinks that arr is an unresolved variable
}
}
答案 8 :(得分:0)
在Optional
枚举中不再支持运算符是非常糟糕的,但是我像这样重载了标准串联运算符(+
):
func +<T: StringProtocol>(lhs: Optional<T>, rhs: Optional<T>) -> String {
return [lhs, rhs].compactMap({ $0 }).joined()
}
然后您可以像这样使用它:
let first: String? = "first"
let last: String? = nil
first + first // "firstfirst"
first + last // "first"
last + first // "first"
last + last // ""
答案 9 :(得分:0)
附加组件:
考虑你有结构:
struct Person {
var firstName: String?
var lastName: String?
}
您可以使用 CustomStringConvertible
extension Person: CustomStringConvertible {
var description: String {
[firstName, lastName].compactMap { $0 }.joined(separator: " ")
}
}
let person1 = Person(firstName "Jeba", lastName: "Moses")
print(person1) // Prints "Jeba Moses"
let person2 = Person(firstName: "Ebenrick", lastName: nil)
print(person2) // Prints "Ebenrick"