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

Swift 4:如何用Filter替代嵌套循环筛选两个对象数组?

用Swift的Filter替代嵌套循环检查属性相等

嗨,我来帮你搞定这个问题!首先先明确咱们的需求:从server数组里筛选出在local数组中存在相同id,但content已经不一样的Message对象,对吧?

先看看原来用嵌套for循环的写法(模拟你可能会写的代码):

var updatedMessages: [Message] = []
for serverMsg in server {
    for localMsg in local {
        if serverMsg.id == localMsg.id && serverMsg.content != localMsg.content {
            updatedMessages.append(serverMsg)
            break // 找到匹配的就跳出内层循环,不用继续找了
        }
    }
}

接下来咱们把它改成用filter的实现,分两种场景给你说明:

场景1:追求性能(推荐,数据量大时更友好)

先把local数组转成一个以id为key、content为value的字典,这样后续查找的效率会大幅提升:

// 先把local的id和content映射成字典,O(n)时间复杂度
let localContentMap = Dictionary(uniqueKeysWithValues: local.map { ($0.id, $0.content) })

// 用filter筛选server数组
let updatedMessages = server.filter { serverMsg in
    // 先判断local里有没有这个id的消息
    guard let localContent = localContentMap[serverMsg.id] else {
        return false // local里没有的话,不算更新的消息
    }
    // 对比内容是否不同,不同的话就保留这个server消息
    return serverMsg.content != localContent
}

这个写法的好处:

  • 完全避免了嵌套循环,代码更简洁,意图更明确
  • 字典查找是O(1)的时间复杂度,整体时间复杂度从嵌套循环的O(n*m)降到了O(n+m),数组元素多的时候性能提升很明显

场景2:代码极简(数据量小时适用)

如果你的数组元素不多,也可以直接在filter里嵌套contains高阶函数,写法更紧凑:

let updatedMessages = server.filter { serverMsg in
    local.contains { localMsg in
        localMsg.id == serverMsg.id && localMsg.content != serverMsg.content
    }
}

这个写法虽然看起来也是“嵌套”,但用声明式的高阶函数替代了手动写循环,代码可读性更强,直接表达了“筛选出server中存在于local里id相同但内容不同的元素”这个意图。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 10:20:03