在条件处于Swift状态时删除集合的最后元素
我试图从字符串数组的后面删除在条件处于Swift状态时删除集合的最后元素,swift,Swift,我试图从字符串数组的后面删除,,,,,直到最后一项包含一些文本为止,但我的实现没有接收到, 我迄今为止的执行情况: var array = ["A", "B", "", "C", "D", " ", " ", ""] while true { if (array.last == " " || array.last == "") { array.removeLast() } else { break } } 我想要的输出是[“A”、“B”
,,,,,直到最后一项包含一些文本为止,但我的实现没有接收到,
我迄今为止的执行情况:
var array = ["A", "B", "", "C", "D", " ", " ", ""]
while true {
if (array.last == " " || array.last == "") {
array.removeLast()
} else {
break
}
}
我想要的输出是[“A”、“B”、“C”、“D”]
但是…
我当前的输出是[“A”、“B”、“u”、“C”、“D”、“u”、“u”]
,其中while
循环在遇到后会简单地中断。
有什么建议吗?为什么不选择“
?
谢谢。将您的状态移动到,同时
并确保您在操作后检查了正确的阵列
var数组=[“A”、“B”、“C”、“D”、“D”、“A”、“B”、“D”]
而array.last==“”| | array.last==“”{
array.removeLast()
}
打印(数组)/[“A”、“B”、“C”、“D”]
基本上,您的解决方案运行良好。但您可以使其更通用于“
”、“
”、“
”、“
”、
解决这个问题的一种方法是反向收集(这是惰性的),并丢弃不需要的项目,直到遇到想要的项目为止。然后,再次反转集合
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),则检查该空格可能会失败。这可能是你首先遇到的问题。因此,修剪字符串(它只从开始和结束处删除字符)并检查结果是否为空字符串。为了好玩,让我们以一种通用的方式扩展数组
,同时从外部提供更灵活的条件
类似于Array
s具有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 = [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]
let数组=[0,1,2,3,0,5,6,7,0,-1,0,-2]
//放下(从尾部)所有小于1的数字
让modified=array.dropLast(while:{(val)->Bool-in
返回值<1
})
打印(修改)/[0,1,2,3,0,5,6,7]
我不知道为什么他们有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]
}
}
扩展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)...)
}
}
你可以把你的条件移动到,而不是true
。它实际上对我来说没有问题。我刚刚在操场上试过,结果是[“A”,“B”,“C”,“D”]
,所以你的代码可以像你想的那样工作。在这种情况下,您不能使用do while。用户只想删除末尾的一个,而不是B和C之间的一个。嘿,我认为这个解决方案实际上比使用while true
要好。投票。我喜欢你的答案,最好把条件放在while中,而不是while-trueAnd,while-truen{if条件{something()}其他{break}}
与while条件{something()}
@user28434:是的。但我遵循的是提问者的编码风格。顺便说一句,新方法是:while array.last?.trimmingCharacters(in:.whitespaces and newlines).isEmpty??false{array.removeLast()}
如果决定反转数组,可能需要使用drop(while:)
<代码>过滤器
在这里不是一个好选择。@Sulthan:噢,太好了!非常感谢您让我意识到这一点,这是一个更好的解决方案!这不应该是returnself[startIndex。。
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"
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"]