多标签嵌套数组过滤异常:Swift的filter函数未达预期效果
Swift过滤逻辑问题排查与修复
原需求
移除所有包含trackingNumber存在于ignoreIds数组中的相关对象,最终objectList中不能保留任何带有需忽略运单编号的条目。
原代码问题分析
当前filter函数的逻辑完全不符合需求:
- 原逻辑是保留那些至少包含一个有效运单(编号不在忽略列表)的
ObjectData,这意味着如果某个ObjectData里同时存在有效和无效运单,它会被保留下来,但无效运单并没有被移除,甚至整个ObjectData也没有被排除。 - 逻辑方向错误:需求是排除包含无效运单的对象,而原代码反其道而行之,保留了存在有效运单的对象。
分场景修复方案
场景1:只要ObjectData中存在任何无效运单,就整个移除该ObjectData
如果需求是彻底清除所有包含无效运单的顶层ObjectData,修改后的代码如下:
func filter() { objectList = objectList.filter { objectData in // 检查当前ObjectData下所有运单的编号都不在忽略列表中 objectData.groups.allSatisfy { group in group.shipments.allSatisfy { shipment in !ignoreIds.contains(shipment.trackingNumber ?? "") } } } }
逻辑说明:
- 使用
allSatisfy替代contains(where:),确保所有层级的运单都符合有效条件才保留该ObjectData。
场景2:仅移除无效运单,同时自动清理空的shipments和groups
如果需求是保留有效运单,同时移除空的运单组和空的分组集合,修改后的代码如下:
func filter() { objectList = objectList.compactMap { objectData in // 过滤每个分组中的无效运单,仅保留有效运单的分组 let validGroups = objectData.groups.compactMap { group in let validShipments = group.shipments.filter { !ignoreIds.contains($0.trackingNumber ?? "") } // 如果过滤后运单为空,丢弃该分组 guard !validShipments.isEmpty else { return nil } var updatedGroup = group updatedGroup.shipments = validShipments return updatedGroup } // 如果过滤后分组为空,丢弃该ObjectData guard !validGroups.isEmpty else { return nil } var updatedObjectData = objectData updatedObjectData.groups = validGroups return updatedObjectData } }
逻辑说明:
- 使用
compactMap逐层过滤,先清理每个分组内的无效运单,再清理空分组,最后清理空的顶层ObjectData,确保最终的objectList只包含有有效运单的完整结构。
内容的提问来源于stack exchange,提问作者Harendra Tiwari
相关产品推荐
相关产品推荐

