Swift:无法删除字符串数组中的“”

时间:2019-03-13 09:23:09

标签: swift

我正在尝试从字符串数组的后面删除""" ",直到最后一项包含一些文本,但是我的实现没有使用" "

到目前为止,我的实现方式是

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

之后就简单地" "循环

有人建议为什么不使用" "吗?
谢谢。

5 个答案:

答案 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 }
}