Swift:如何基于索引数组低复杂度提取源数组的对应元素
Swift 按索引数组提取元素的低复杂度实现
原实现的核心问题
你写的循环逻辑从根上就存在偏差,不仅性能达不到要求,甚至无法正常运行:
- 匹配方向完全错误:需求是遍历索引数组b存储的每一个目标位置,再去源数组a取对应元素,而非遍历a的全量下标,和同位置的b数组元素做相等判断。按你原来的循环,遍历到i=3时就会因为b数组只有3个有效元素(索引范围0~2)直接触发越界崩溃,根本得不到预期的输出结果
- 冗余遍历浪费性能:原写法需要遍历源数组a的全部n个元素,当a的规模远大于b时(比如a存了10万条数据,你只需要取其中3个位置的元素),绝大多数遍历都是无意义的无效计算
最优效率的实现方案
按索引取值的逻辑本身理论最低时间复杂度就是O(m)(m为索引数组b的元素个数),完全不需要扫描整个源数组,具体可以封装一个通用泛型函数复用:
/// 从源数组按给定索引提取对应元素(自带越界保护) /// - Parameters: /// - source: 存储全量元素的源数组 /// - indices: 需要提取的目标位置索引数组 /// - Returns: 按索引顺序提取到的元素集合 func extractElements<Element>(from source: [Element], indices: [Int]) -> [Element] { indices.compactMap { targetIndex in // 跳过超出源数组下标的无效值,避免运行时崩溃 guard source.indices.contains(targetIndex) else { return nil } return source[targetIndex] } }
实际调用示例
对应你给出的测试数组,可以直接得到预期结果:
let a = ["apple","banana","orange","pomelo","kiwi","melon"] let b = [1, 2, 4] let extracted = extractElements(from: a, indices: b) // 输出结果:["banana", "orange", "kiwi"],和需求完全匹配
方案效率说明
- 全程仅遍历索引数组b的所有元素,不对源数组做全量扫描,哪怕源数组存储百万级数据,只要b里只有3个索引,就仅执行3次数组查询,没有冗余计算
- 泛型设计支持所有类型的源数组,不需要针对不同元素类型重复写提取逻辑
- 自带越界校验,遇到索引数组里的非法值时会自动跳过,不会触发运行时崩溃
如果不需要生成结果数组、只是要直接处理对应元素(比如直接打印),可以简化成更轻量的遍历写法:
b.forEach { targetIndex in guard a.indices.contains(targetIndex) else { return } print(a[targetIndex]) }
内容的提问来源于stack exchange,提问作者Mommy
相关产品推荐
相关产品推荐

