我正在尝试从字符串数组的后面删除""
和" "
,直到最后一项包含一些文本,但是我的实现没有使用" "
。
到目前为止,我的实现方式是
var array = ["A", "B", "", "C", "D", " ", " ", ""]
while true {
if (array.last == " " || array.last == "") {
array.removeLast()
} else {
break
}
}
我想要的输出是["A", "B", "", "C", "D"]
,但是...
我当前的输出是["A", "B", "", "C", "D", " ", " "]
,其中while
在遇到breaks
" "
循环
有人建议为什么不使用" "
吗?
谢谢。
答案 0 :(得分:3)
将条件移至while
,并确保在操作后检查正确的数组。
var array = ["A", "B", "", "C", "D", " ", " ", ""]
while array.last == " " || array.last == "" {
array.removeLast()
}
print(array) // ["A", "B", "", "C", "D"]
答案 1 :(得分:3)
解决此问题的一种方法是反转集合(这是偷懒完成的)并丢弃不需要的项目,直到遇到需要的项目为止。然后,再次反转集合。
let array = ["A", "B", "", "C", "D", " ", " ", ""]
let filtered = array.reversed().drop(while: {
$0.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty
}).reversed() as [String]
print(filtered) // "["A", "B", "", "C", "D"]\n"
请注意,如果" "
的检查不是正常空间(例如,不间断空格(Unicode检查点U + 00A0)),则可能会失败。首先,这可能是您遇到的问题。因此,请修剪字符串(仅从开头和结尾删除字符),然后检查结果是否为空字符串。
答案 2 :(得分:3)
我不知道为什么他们有drop(while:)
而没有实现dropLast(while:)
。以下实现适用于任何集合:
extension Collection {
func dropLast(while predicate: (Element) throws -> Bool) rethrows -> SubSequence {
guard let index = try indices.reversed().first(where: { try !predicate(self[$0]) }) else {
return self[startIndex..<startIndex]
}
return self[...index]
}
}
"123".dropLast(while: \.isWholeNumber) // ""
"abc123".dropLast(while: \.isWholeNumber) // "abc"
"123abc".dropLast(while: \.isWholeNumber) // "123abc"
扩展RangeReplaceableCollection,我们还可以实现remove(while:)
和removeLast(while:)
:
extension RangeReplaceableCollection {
mutating func remove(while predicate: (Element) throws -> Bool) rethrows {
guard let index = try indices.first(where: { try !predicate(self[$0]) }) else {
removeAll()
return
}
removeSubrange(..<index)
}
mutating func removeLast(while predicate: (Element) throws -> Bool) rethrows {
guard let index = try indices.reversed().first(where: { try !predicate(self[$0]) }) else {
removeAll()
return
}
removeSubrange(self.index(after: index)...)
}
}
var string = "abc123"
string.removeLast(while: \.isWholeNumber)
string // "abc"
var string2 = "abc123"
string2.remove(while: \.isLetter)
string2 // "123"
var array = ["A", "B", "", "C", "D", " ", " ", ""]
array.removeLast { $0 == "" || $0 == " " }
array // ["A", "B", "", "C", "D"]
答案 3 :(得分:1)
只是为了好玩,让我们以通用的方式扩展Array
的此功能,同时在外部提供条件以获得更大的灵活性。
类似于Array
拥有drop(while:)
的情况,我们可以像这样制作dropLast(while:)
:
extension Array {
func dropLast(while handler: (Element)->Bool) -> Array {
var array = self
while let last = array.last, handler(last) {
array.removeLast()
}
return array
}
}
let array = ["", "A", "B", "", "C", "D", " ", " ", ""]
let modified = array.dropLast { $0.trimmingCharacters(in: .whitespaces).isEmpty }
print(modified) //["", "A", "B", "", "C", "D"]
它也可以处理其他类型的数组,并且由于该条件未纳入功能中,因此它具有灵活性和可重用性。
let array = [0, 1, 2, 3, 0, 5, 6, 7, 0, -1, 0, -2]
//Drop (from tail) all numbers less than 1
let modified = array.dropLast(while: { (val) -> Bool in
return val < 1
})
print(modified) //[0, 1, 2, 3, 0, 5, 6, 7]
答案 4 :(得分:0)
基本上,您的解决方案可以正常运行。但是您可以使其更通用,例如“ ”,“
”,“”,“
”, ....:
import Foundation
var array = ["A", "B", "", "C", "D", " ", " ", ""]
while true {
let shouldRemoveLast = array.last?.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty ?? false
if (shouldRemoveLast) { array.removeLast() } else { break }
}