Swift 基础 - Array remove 操作大全

6,246 阅读3分钟

系统 API

remove(at:)

移除并返回特定索引的元素。

Complexity: O(n)

var measurements: [Double] = [1.1, 1.5, 2.9, 1.2, 1.5, 1.3, 1.2]
let removed = measurements.remove(at: 2)
print(measurements)
// Prints "[1.1, 1.5, 1.2, 1.5, 1.3, 1.2]"

removeFirst()

移除并返回集合里的第一个元素。 注意:调用该函数的集合不可为空。

Complexity: O(n)

var bugs = ["Aphid", "Bumblebee", "Cicada", "Damselfly", "Earwig"]
bugs.removeFirst()
print(bugs)
// Prints "["Bumblebee", "Cicada", "Damselfly", "Earwig"]"

removeFirst(_:)

从集合头部,移除指定数量的元素。传入的参数必须大约等于 0 ,并且要小于等于集合的数量。

Complexity: O(n)

var bugs = ["Aphid", "Bumblebee", "Cicada", "Damselfly", "Earwig"]
bugs.removeFirst(3)
print(bugs)
// Prints "["Damselfly", "Earwig"]"

注意:调用该函数,可能会使该集合之前存在的索引失效。

var bugs = ["Aphid", "Bumblebee", "Cicada", "Damselfly", "Earwig"]
let originalIndexs = bugs.indices
bugs.removeFirst(3)

// 此处的 originalIndexs 已失效,下面的代码会Fatal error: Index out of range
for i in originalIndexs {
    print(bugs[i])
}
// 需要冲新获取索引
let changeIndexs = bugs.indices
for i in changeIndexs {
    print(bugs[i])
}

removeLast()

移除并返回集合的最后一个元素。

注意:调用该函数的集合不可为空,且调用该函数,会导致该集合之前存储的索引失效。

Complexity: O(1)

var bugs = ["Aphid", "Bumblebee", "Cicada", "Damselfly", "Earwig"]
bugs.removeLast()
print(bugs)
// Prints "["Aphid", "Bumblebee", "Cicada", "Damselfly"]"

removeLast(_:)

从集合头部,移除特定数量的元素。传入的参数必须大约等于 0 ,并且要小于等于集合的数量。

Complexity: O(k),k 该函数传入的参数。

注意:如果试图移除大于集合数量的元素,会导致运行时错误。调用该函数,会导致该集合之前存储的索引失效。

var bugs = ["Aphid", "Bumblebee", "Cicada", "Damselfly", "Earwig"]
bugs.removeLast(3)
print(bugs)
// Prints "["Aphid", "Bumblebee", "Cicada", "Damselfly"]"

removeSubrange(_:)

移除某个具体区间内的元素。传入的区间必须是集合中的有效区间。调用该函数,会导致该集合之前存储的索引失效。

Complexity: O(n)

var measurements = [1.2, 1.5, 2.9, 1.2, 1.5]
measurements.removeSubrange(1..<4)
print(measurements)
// Prints "[1.2, 1.5]"

removeAll(where:)

移除所有符合条件的元素。

Complexity: O(n)

var phrase = "The rain in Spain stays mainly in the plain."

let vowels: Set<Character> = ["a", "e", "i", "o", "u"]
phrase.removeAll(where: { vowels.contains($0) })
// phrase == "Th rn n Spn stys mnly n th pln."

removeAll(keepingCapacity:)

移除集合中的所有元素。传递true可以在删除数组元素后保留其现有容量。默认值为false。

Complexity: O(n)

var measurements = [1.2, 1.5, 2.9, 1.2, 1.5]
// 等同于 removeAll()
measurements.removeAll(keepingCapacity: false)
print(measurements)
// []

popLast()

移除并返回集合中的最后一个元素。如果有最后一个元素,则返回最后一个元素,没有则返回 nil 。调用该函数,会导致该集合之前存储的索引失效。

Complexity: O(1)

var measurements = [String]()
let last = measurements.popLast()
print(last)
nil

扩展

循环删除集合中特定索引的元素

extension Array {
    mutating func removeSpecifiedIndices(_ indices: [Int]) {
        let sortedIndices = indices.sorted().reversed()
        for i in sortedIndices {
            guard i < count else { return }
            remove(at: i)
        }
    }
}

var intArr = [1,2,3,4,5,6,7]
intArr.removeSpecifiedIndices([1,2,5])
print(intArr)
//[1, 4, 5, 7]

循环删除集合中特定索引的元素(泛型版)

extension MutableCollection where Self: RangeReplaceableCollection {
    private mutating func remove<C>(elementsAtSortedIndices indicesToRemove: C) where
        C: Collection,
        C.Element == Index {
        // Shift the elements we want to keep to the left.
        var destIndex = indicesToRemove.first!
        precondition(indices.contains(destIndex), "Index out of range")
        
        var srcIndex = index(after: destIndex)
        var previousRemovalIndex = destIndex
        func shiftLeft(untilIndex index: Index) {
            precondition(index != previousRemovalIndex, "Duplicate indices")
            while srcIndex < index {
                swapAt(destIndex, srcIndex)
                formIndex(after: &destIndex)
                formIndex(after: &srcIndex)
            }
            formIndex(after: &srcIndex)
        }
        let secondIndex = indicesToRemove.index(after: indicesToRemove.startIndex)
        for removeIndex in indicesToRemove[secondIndex...] {
            precondition(indices.contains(removeIndex), "Index out of range")
            shiftLeft(untilIndex: removeIndex)
        }
        shiftLeft(untilIndex: endIndex)
        
        // Remove the extra elements from the end of the collection.
        removeSubrange(destIndex..<endIndex)
    }
    mutating func removeSpecificElements<C>(elementsAtIndices indicesToRemove: C) where
        C: Collection,
        C.Element == Index {
        guard !indicesToRemove.isEmpty else {
            return
        }
        
        // Check if the indices are sorted.
        var isSorted = true
        var prevIndex = indicesToRemove.first!
        let secondIndex = indicesToRemove.index(after: indicesToRemove.startIndex)
        for index in indicesToRemove[secondIndex...] {
            if index < prevIndex {
                isSorted = false
                break
            }
            prevIndex = index
        }
        
        if isSorted {
            remove(elementsAtSortedIndices: indicesToRemove)
        } else {
            remove(elementsAtSortedIndices: indicesToRemove.sorted())
        }
    }
}

循环删除集合中所有元素

var arr = [1,2,3,4,5]
for (i, value) in arr.enumerated().reversed() {
    arr.remove(at: i)
}

print(arr)