You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift 4数组去重算法中移除元素时触发运行时错误求助

解决Swift数组去重时的索引越界问题

这个问题我太熟悉啦!你遇到的运行时错误是数组索引越界导致的,核心原因是你在遍历数组的同时修改了它的长度,让后续循环的索引超出了数组实际的范围。

问题分析

当你执行array.remove(at: i)时,数组的长度会立即减1,但你的循环范围是基于初始数组长度生成的0 ..< array.count。举个极端例子:如果输入数组是[4,4,4],第一次循环i=0,元素被加入集合;i=1时发现重复,执行移除操作,数组变成[4,4](长度为2);接下来循环会走到i=2,这时候array[2]根本不存在,直接触发索引越界崩溃。

解决方案1:反向遍历数组

最直接的修复方式是从后往前遍历数组。因为反向遍历时,你移除当前索引的元素不会影响还没遍历到的前面的索引(那些索引值更小,不会因为数组长度缩短而失效)。

修改后的代码:

func unique(_ arr:[Int]) -> [Int] {
    var array = arr
    var uniqueSet = Set<Int>()
    // 反向遍历,避免索引越界问题
    for i in (0 ..< array.count).reversed() {
        if uniqueSet.contains(array[i]) {
            print("remove \(array[i]) for i \(i) from array")
            array.remove(at: i)
        } else {
            print("insert \(array[i]) into set")
            uniqueSet.insert(array[i])
        }
    }
    return array
}
print(unique([1, 2, 4, 4, 5, 6]))

解决方案2:用Swift风格的方式构建新数组(更推荐)

其实不需要在原数组上修改,我们可以用reduce方法直接构建一个去重后的新数组,这样既不会有索引问题,代码也更简洁,还能保持原数组的顺序:

func unique(_ arr:[Int]) -> [Int] {
    var uniqueSet = Set<Int>()
    return arr.reduce(into: [Int]()) { result, element in
        if !uniqueSet.contains(element) {
            uniqueSet.insert(element)
            result.append(element)
        }
    }
}
print(unique([1, 2, 4, 4, 5, 6]))

这种方法的思路是遍历原数组,把第一次出现的元素加入结果数组和集合,后续重复的元素直接跳过,完全避免了修改数组长度带来的风险。

内容的提问来源于stack exchange,提问作者Maria 9905

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 08:52:54