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
相关产品推荐
相关产品推荐

