【问题标题】:Remove the last occurrence of an element in a Swift array删除 Swift 数组中最后一次出现的元素
【发布时间】:2015-11-04 09:41:59
【问题描述】:

我需要删除 [Bool] 数组中最后一次出现的特定元素。例如,在 JavaScript 中,这将是:

var k = [true, true, false];
k.splice(k.lastIndexOf(true), 1);
==> [true, false]

如何在 Swift 中实现相同的行为?

【问题讨论】:

  • 让我直说。您想删除数组中给定对象的最后一次出现。因此,如果您的数组是 var array = ["apple", "pear", "banana", "apple", "orange"] 您希望您的 array.removeLastOccurrenceOf("apple") 将数组更改为 ["apple", "pear", "banana", "orange"]
  • 对于那些想要删除数组中的最后一个元素的人,请参阅this answer

标签: arrays swift indexing boolean


【解决方案1】:

您可以通过反向枚举轻松找到最后一次出现的值。当您找到您要查找的值时,只需将其删除并从循环中中断即可。使用reverse()倒序枚举索引范围:

for i in array.indices.reversed() where array[i] == searchValue {
    array.remove(at: i)
    break
}

【讨论】:

  • 谢谢!快速回答并解释了我的问题。
  • 你可以写array.indices.reverse(),而不是(0..<array.count).reverse()。如果你这样做,它也适用于非整数索引(例如字符串)和非从零开始的索引(例如非数组切片)。
  • @AirspeedVelocity 感谢您的宝贵建议 - 我已将其纳入答案。
  • Swift 3 和 4 的小改动:reverse() 现在是 reversed(),removeAtIndex(i) 现在是 remove(at: i)
【解决方案2】:

Xcode 8.2 • Swift 3.0.2

var k = [true, true, true, false, true, false]

if let index = k.reversed().index(of: true) {
    k.remove(at: index.base - 1)
}

print(k)   // "[true, true, true, false, false]"

如果您想创建一个扩展来将此功能添加到 Array,您需要将其限制为可等价的元素:

extension Array where Element: Equatable {
    ///  Returns the last index where the specified value appears in the collection.
    ///  After using lastIndex(of:) to find the last position of a particular element in a collection, you can use it to access the element by subscripting.
    /// - Parameter element: The element to find the last Index
    func lastIndex(of element: Element) -> Index? {
        if let index = reversed().index(of: element) {
            return  index.base - 1
        }
        return nil
    }
    /// Removes the last occurrence where the specified value appears in the collection.
    /// - Returns: True if the last occurrence element was found and removed or false if not.
    /// - Parameter element: The element to remove the last occurrence.
    @discardableResult
    mutating func removeLastOccurrence(of element: Element) -> Bool {
        if let index = lastIndex(of: element) {
            remove(at: index)
            return true
        }
        return false
    }
}

游乐场测试

var k = [true, true, true, false, true, false]

k.removeLastOccurrence(of: true)
print(k)                        // "[true, true, true, false, false]"

【讨论】:

    【解决方案3】:

    我不认为有像lastIndexOf 这样的内置函数,所以它的工作量更大。

    var removeIndex: Int?
    
    for (index, item) in enumerate(arr) {
        if item == search {
            removeIndex = index 
        }
    }
    
    if let removeIndex = removeIndex {
        arr.removeAtIndex(removeIndex)
    }
    

    其中arr 是您正在搜索的数组(在您的示例中为k),search 是您正在搜索的内容(在您的示例中为true)。

    【讨论】:

    • 这可行,但您并不需要数组。您可以简单地将最后一个匹配索引存储到 Int 中,然后从数组中删除该索引处的对象。更少的存储空间,更简单的代码。
    • 同意,这样更清洁、更高效——我改变了答案。
    • 现在作为最后的清理,为什么不在最后一个 if 语句中使用“可选绑定”:if let removeIndex = removeIndex {arr.removeAtIndex(removeIndex!)}
    • 好提示。绑定不需要强制展开removeIndex!,对吧? arr.removeAtIndex(removeIndex) 应该可以工作。
    • 注意,对于 Swift 2.0,您需要更改为 arr.enumerate()
    猜你喜欢
    • 2021-02-25
    • 2020-04-29
    • 2020-06-17
    • 1970-01-01
    • 2012-01-05
    • 1970-01-01
    • 1970-01-01
    • 2015-12-12
    • 1970-01-01
    相关资源
    最近更新 更多