arrays - 从 Swift 中的 Int 数组中删除重复项(for-in-loop)
问题描述
有很多方法可以快速从数组中删除重复项,但我正在尝试使用for in 循环来管理它。谁能解释一下,为什么这段代码不起作用?
致命错误:索引超出范围
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)
解决方案
有问题的部分是迭代一个数组并同时更新该数组。在这种情况下,在迭代时删除一个元素。
移除一个元素会减少数组长度 ( 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
通过使用 a保留添加的元素,可以大大降低复杂性(性能) :
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($0).inserted }
推荐阅读
- macos - 公证 java 应用程序以在 mac 应用程序商店上分发
- haskell - 具有不同数量参数的 Haskell 函数
- asp.net - Asp.Net Core SignalR + Angular 6 问题
- c - 使用 C 填充和打印带有随机数的数组
- android - 第一次触摸时 MotionLayout 出现视觉故障
- python - pyqt5封装的C++对象是否还存在
- python - 1 Integer 似乎正在取另一个 Python 的值
- python - Python:字典内的嵌套列表?
- c# - 为什么编译器不抱怨并非所有路径都返回?
- python-3.x - 创建具有 3 个级别的列表,包含子列表值的每个组合