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

TypeScript/JavaScript如何筛选两个对象数组中属性变更的项

问题原因

_.differenceBy的匹配逻辑不符合你的需求:它只会提取第一个数组中,指定属性值在第二个数组里完全不存在的元素。你传入的比较属性是checked,两个数组里本来就同时存在true、false两种checked值,所以第一个数组里所有元素的checked值都能在第二个数组里找到匹配,最终自然返回空数组。
你真正需要的逻辑是:先通过唯一标识id匹配两个数组里的同一条数据,再对比同一条数据的checked值是否发生变化,直接按checked做差集完全没考虑id的对应关系,结果肯定不对。

实现方法

原生JS实现(无需额外依赖)

先把默认状态数组转成id为键的映射,再遍历当前状态数组逐一对比即可,执行性能更高:

const defaultList = [
  {id: "1", name: "item1", checked: true},
  {id: "2", name: "item2", checked: true},
  {id: "3", name: "item3", checked: true}
]
const currentList = [
  {id: "1", name: "item1", checked: true},
  {id: "2", name: "item2", checked: true},
  {id: "3", name: "item3", checked: false}
]

const defaultMap = new Map(defaultList.map(item => [item.id, item]))
const changedList = currentList.filter(item => {
  const originItem = defaultMap.get(item.id)
  return originItem && originItem.checked !== item.checked
})

// changedList 输出结果:[{id: "3", name: "item3", checked: false}]

Lodash实现

如果项目已经引入lodash,可以用_.differenceWith自定义匹配规则,注意比较函数里要同时匹配id和checked值:

const changedList = _.differenceWith(currentList, defaultList, (curr, origin) => {
  // 函数返回true代表两项"无差异",会被过滤掉,这里判断id相同且checked一致的无差异场景
  return curr.id === origin.id && curr.checked === origin.checked
})

注意两个数组的传入顺序不要写反,第一个参数要传当前状态数组,才能拿到变更后的最新对象作为结果。

补充说明

如果业务场景里存在某条id只在其中一个数组出现的情况(比如新增项、删除项),可以在上述逻辑基础上额外加判断,把这类数据也归入变更结果即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 01:27:17