如何在嵌套Item数组中快速查找指定ID的元素?
高效查找并更新嵌套Item的方案
针对你遇到的嵌套Item结构体查找效率低的问题,这里提供两种实用方案:
方案1:改用类+ID映射字典(最高效)
结构体是值类型,无法直接通过引用修改;而类是引用类型,配合ID映射字典可以实现O(1)时间复杂度的查找和修改,是最适合频繁操作的方案。
修改后的代码
class Item: Identifiable { let id: UUID = UUID() var nameOfItem: String var nestedItems: [Item] init(nameOfItem: String, nestedItems: [Item] = []) { self.nameOfItem = nameOfItem self.nestedItems = nestedItems } } // 核心:维护UUID到Item实例的映射字典,实现快速查找 var itemIDMap: [UUID: Item] = [:] var myArray: [Item] = [] // 封装添加逻辑,确保字典和数组/嵌套列表同步 func addItem(_ item: Item, to parent: Item? = nil) { itemIDMap[item.id] = item if let parent = parent { parent.nestedItems.append(item) } else { myArray.append(item) } } // 封装删除逻辑,保持字典一致性 func removeItem(with id: UUID) { guard let item = itemIDMap.removeValue(forKey: id) else { return } // 找到父节点并从嵌套列表中移除 if let parent = findParent(of: item) { parent.nestedItems.removeAll { $0.id == id } } else { myArray.removeAll { $0.id == id } } } // 辅助方法:递归查找Item的父节点 private func findParent(of targetItem: Item) -> Item? { func search(in items: [Item]) -> Item? { for item in items { if item.nestedItems.contains(where: { $0.id == targetItem.id }) { return item } if let parent = search(in: item.nestedItems) { return parent } } return nil } return search(in: myArray) }
使用方式
// 假设已有目标Item的UUID let targetUUID = UUID() // 直接查找并修改,O(1)效率 if let targetItem = itemIDMap[targetUUID] { targetItem.nameOfItem = "更新后的名称" // 其他属性修改同理 }
方案2:保留结构体+递归更新(无类型变更需求时用)
如果必须使用结构体(比如依赖值类型的不可变性特性),可以通过递归遍历并生成更新后的副本实现修改。
扩展方法实现
extension Item { /// 递归查找匹配ID的Item,应用修改后返回更新后的自身副本 func updated(with targetID: UUID, modify: (inout Item) -> Void) -> Item { var updatedSelf = self // 匹配当前Item,直接修改 if updatedSelf.id == targetID { modify(&updatedSelf) return updatedSelf } // 递归处理嵌套Item updatedSelf.nestedItems = updatedSelf.nestedItems.map { $0.updated(with: targetID, modify: modify) } return updatedSelf } }
使用方式
// 更新整个数组(因为结构体是值类型,需要替换根层级) myArray = myArray.map { $0.updated(with: targetUUID) { item in item.nameOfItem = "新名称" // 可以修改任意属性,包括新增嵌套项 item.nestedItems.append(Item(nameOfItem: "新增嵌套项", nestedItems: [])) } }
方案对比
- 方案1:查找和修改效率最高(O(1)),但需要将结构体改为类,适合频繁修改、嵌套层级深的场景。
- 方案2:保持结构体的特性,但修改时会生成副本,效率取决于嵌套深度,适合修改频率低、依赖值类型不可变性的场景。
内容的提问来源于stack exchange,提问作者swiftPunk
相关产品推荐
相关产品推荐

