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

Swift 4中过滤对象数组并移除元素:解决索引越界问题

解决数组遍历删除时的索引越界问题

嘿,我完全懂你遇到的这个坑!之前我也踩过类似的——用stride(from:to:by:)的时候,to参数会在循环开始前就固定为数组初始的count值,哪怕你中途删除元素改变了数组长度,循环还是会按原来的次数执行,自然就会碰到索引越界的问题。

下面给你两种最靠谱的解决方式,按需选择:

方法一:用filter过滤数组(推荐)

这是最简洁安全的方式,完全不需要手动处理索引。filter会创建一个新数组,只保留符合你条件的元素,直接避开了遍历删除的所有坑。

举个例子,假设你要移除数组中所有等于2的元素:

var numbers = [1, 2, 3, 2]
// 过滤掉所有值为2的元素
numbers = numbers.filter { $0 != 2 }
print(numbers) // 输出: [1, 3]

这种方式代码干净,性能也不错,除非你有必须原地修改数组的特殊需求,否则优先用这个。

方法二:原地删除的正确遍历方式

如果必须原地修改数组(比如删除时需要执行额外逻辑),推荐两种方式:

1. 倒序遍历

倒着遍历数组,删除元素不会影响前面未遍历的索引,因为前面的元素位置不会被移动。

var numbers = [1, 2, 3, 2]
// 从最后一个索引开始,往前遍历
for i in stride(from: numbers.count - 1, through: 0, by: -1) {
    if numbers[i] == 2 {
        numbers.remove(at: i)
        print("Removed at index \(i), current count: \(numbers.count)")
    }
}
print(numbers) // 输出: [1, 3]

2. 使用while循环手动控制索引

用while循环动态检查数组的最新count,并且根据是否删除元素来决定是否递增索引:

var numbers = [1, 2, 3, 2]
var i = 0
while i < numbers.count {
    if numbers[i] == 2 {
        numbers.remove(at: i)
        // 删除元素后,后面的元素会移到当前i的位置,所以不要递增索引
    } else {
        // 没删除元素,正常递增索引
        i += 1
    }
}
print(numbers) // 输出: [1, 3]

这样就能避免你遇到的问题——每次循环都会用数组当前的count来判断,不会出现索引超出范围的情况。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 10:04:41