从 Swift 中的 Int 数组中删除重复项(for-in-loop)

Remove duplicates from array of Int in Swift (for-in-loop)

在 swift 中有很多方法可以从数组中删除重复项,但我正在尝试使用 for in loop 来管理它。 谁能解释一下,为什么这段代码不起作用?

Fatal error: Index out of range

func deleteDuplicates(array: [Int]) -> [Int] {

    var newArray = array

    for i in 0 ..< newArray.count - 1  {
        for j in i + 1 ..< newArray.count  {

            if newArray[i] == newArray[j] {
                newArray.remove(at: j)
            }
        }
    }
    return newArray
}

array1 = [0, 1, 8, 3, 4, 4, 3, 6, 7, 11, 4, 5, 5, 8]
deleteDuplicates(array: array1)

一个原因是您正在修改同一个数组,您在该数组上 运行 两个 for 循环。要详细了解,请按照 Martin 所说的那样使用调试器。并且

这可以使用一个 for 循环和 Set 来完成:

var newArray = [0, 1, 8, 3, 4, 4, 3, 6, 7, 11, 4, 5, 5, 8]
var array = Set<Int>()
for i in  newArray {
    array.insert(i)
}
print(array)

输出:

[4, 5, 3, 0, 1, 8, 6, 11, 7]

有问题的部分是遍历数组并同时更新该数组。在这种情况下,在迭代时删除一个元素。

删除元素会减少数组长度 (count) 并更改索引。因此在

for j in i + 1 ..< array.count  {
    if array[i] == array[j] {
        newArray.remove(at: j)
    }
}

删除第一个索引后,您的其他索引将失效。请注意,count 在实际迭代之前始终只读取一次。

这就是为什么在迭代过程中删除元素既危险又复杂的原因之一。您可以通过维护已删除元素的数量并相应地更新索引来修复它。或者你可以向后迭代:

var newArray = array

for i in (0 ..< newArray.count - 1).reversed()  {
    for j in (i + 1 ..< newArray.count).reversed()  {
        if newArray[i] == newArray[j] {
            newArray.remove(at: j)
        }
    }
}
return newArray

您仍在更改索引,count但由于您是向后迭代,因此您只更改已使用的索引。

一般来说,构建一个新数组比更新当前数组更简单也更安全:

var newArray: [Int] = []

for value in array {
    if !newArray.contains(value) {
       newArray.append(value)
    }
}

return newArray

通过使用 Set 保留添加的元素可以大大降低复杂性(性能):

var newArray: [Int] = []
var foundElements: Set<Int> = []

for value in array {
    if foundElements.insert(value).inserted {
       newArray.append(value)
    }
}

return newArray

可以使用filter简化:

var foundElements: Set<Int> = []
return array.filter { foundElements.insert([=14=]).inserted } 

这是您可以尝试的一种简单方法。

func removeDuplicates(_ nums: inout [Int]) {    
        var arrLen = nums.count
        var index = 0
        while(index < arrLen - 1){
            if nums[index] == nums[index+1] {
                nums.remove(at: index)
                arrLen = arrLen - 1
            }else{
                index = index+1
            }
        }
    }

无需创建新数组即可删除重复项。