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

Swift中如何按AccountNumber合并NSArray与NSMutableArray的字典数组?

解决NSMutableArray与NSArray基于AccountNumber的合并问题

我看了你写的合并数组的代码,发现几个关键问题导致功能不符合预期:

  • 重复添加元素:内层循环里只要不匹配就执行logOrderMutArray.add(openOrderArray[j]),这会让同一个openOrder元素被重复添加N次(N等于logOrderMutArray的元素数量),完全不是你想要的结果。
  • 替换逻辑错误:你把openOrder的元素放到了editDict["newlyAdded"]这个键下,而不是直接用openOrder的元素替换原数组中的对应元素,根本没实现“替换匹配元素”的需求。
  • 类型处理不安全:大量使用as!强制解包,很容易因为数据格式问题崩溃,而且依赖Objective-C的集合类(NSDictionary/NSMutableArray)不如用Swift原生集合更简洁安全。

正确的实现思路

我们可以用字典做快速映射来优化逻辑,把时间复杂度从嵌套循环的O(n*m)降到O(n+m),同时避免重复添加:

  1. 先把openOrderArray转换成以AccountNumber为key的字典,方便快速查找对应元素。
  2. 遍历logOrderMutArray,检查每个元素的AccountNumber是否在字典中存在:存在就用openOrder的元素替换,不存在就保留原元素。
  3. 最后把openOrder中所有没在logOrder里出现过的元素,添加到logOrderMutArray中。

推荐的Swift原生实现代码

这种写法更符合Swift的语言习惯,类型安全且逻辑清晰:

func mergeOrderAndOpenOrderArrayData() {
    // 将NSArray转为Swift原生数组,方便后续处理
    guard let openOrders = openOrderArray as? [[String: Any]] else { return }
    
    // 构建AccountNumber到订单的映射字典,过滤掉没有AccountNumber的无效元素
    let openOrderDict = Dictionary(uniqueKeysWithValues: openOrders.compactMap { order in
        guard let accountNum = order["AccountNumber"] as? String else { return nil }
        return (accountNum, order)
    })
    
    // 处理原日志订单数组:替换匹配的元素
    guard var logOrders = logOrderMutArray as? [[String: Any]] else { return }
    logOrders = logOrders.map { logOrder in
        guard let accountNum = logOrder["AccountNumber"] as? String,
              let matchedOpenOrder = openOrderDict[accountNum] else {
            return logOrder
        }
        // 直接返回openOrder的元素完成替换
        return matchedOpenOrder
    }
    
    // 找出openOrder中未在logOrder里出现的元素
    let logAccountNumbers = Set(logOrders.compactMap { $0["AccountNumber"] as? String })
    let newOrdersToAdd = openOrders.filter { order in
        guard let accountNum = order["AccountNumber"] as? String else { return false }
        return !logAccountNumbers.contains(accountNum)
    }
    
    // 更新原NSMutableArray
    logOrderMutArray.removeAllObjects()
    logOrderMutArray.addObjects(from: logOrders + newOrdersToAdd)
}

保留Objective-C风格的实现(直接操作NSMutableArray)

如果你更习惯用Objective-C的集合类,也可以这样写:

func mergeOrderAndOpenOrderArrayData() {
    // 构建openOrder的AccountNumber映射字典
    let openOrderDict = NSMutableDictionary()
    for order in openOrderArray {
        guard let accountNum = (order as AnyObject).value(forKey: "AccountNumber") as? String else {
            continue
        }
        openOrderDict[accountNum] = order
    }
    
    // 遍历原数组,替换匹配的元素,同时移除字典中已匹配的项
    for i in 0..<logOrderMutArray.count {
        let logOrder = logOrderMutArray[i]
        guard let accountNum = (logOrder as AnyObject).value(forKey: "AccountNumber") as? String,
              let matchedOpenOrder = openOrderDict[accountNum] else {
            continue
        }
        logOrderMutArray.replaceObject(at: i, with: matchedOpenOrder)
        openOrderDict.removeObject(forKey: accountNum)
    }
    
    // 添加剩余未匹配的openOrder元素
    logOrderMutArray.addObjects(from: openOrderDict.allValues)
}

这两种写法都能实现你的需求:匹配到相同AccountNumber的元素就替换,未匹配的就添加,而且不会出现重复添加的问题,同时处理了可选值避免崩溃。

内容的提问来源于stack exchange,提问作者B.Saravana Kumar

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 06:27:01