JS对比两个对象数组并更新主数组元素的优化实现咨询
修正数组筛选逻辑并优化实现方案
嘿,我来帮你搞定这个问题!你当前的代码主要是逻辑搞反了,而且嵌套循环的效率也可以优化,咱们一步步来修正和改进:
问题分析
你现在的代码是把出现在filtered数组里的项的selected设为false,但需求刚好相反:需要把主数组data中没出现在filtered里的项的selected设为false,同时保留在filtered里的项的selected为true。另外,嵌套for...in循环的查找效率偏低,尤其是当数组元素较多时。
原生JS修正方案(高效版)
我们可以先把filtered里的value提取成一个Set,这样查找元素的时间复杂度从O(n)降到O(1),效率大幅提升:
const data = [{ color: "red", value: "#f00", selected: true }, { color: "green", value: "#0f0", selected: true }, { color: "blue", value: "#00f", selected: true }, { color: "cyan", value: "#0ff", selected: true }, { color: "magenta", value: "#f0f", selected: true }, { color: "yellow", value: "#ff0", selected: true }, { color: "black", value: "#000", selected: true } ] const filtered = [{ color: "magenta", value: "#f0f", selected: true }, { color: "green", value: "#0f0", selected: true }, { color: "black", value: "#000", selected: true }] // 提取filtered中所有项的value到Set,快速查找 const filteredValueSet = new Set(filtered.map(item => item.value)); // 遍历data,判断当前项是否在filtered中,直接赋值selected data.forEach(item => { item.selected = filteredValueSet.has(item.value); }); console.log(data);
执行这段代码后,就能得到你预期的输出结果。
Lodash优化方案
如果你的项目已经在用Lodash,有两种更简洁的实现方式:
方案1:修改原数组(和原生方案逻辑一致)
用_.keyBy把filtered转成以value为键的对象,再快速判断:
const _ = require('lodash'); const data = [{ color: "red", value: "#f00", selected: true }, { color: "green", value: "#0f0", selected: true }, { color: "blue", value: "#00f", selected: true }, { color: "cyan", value: "#0ff", selected: true }, { color: "magenta", value: "#f0f", selected: true }, { color: "yellow", value: "#ff0", selected: true }, { color: "black", value: "#000", selected: true } ] const filtered = [{ color: "magenta", value: "#f0f", selected: true }, { color: "green", value: "#0f0", selected: true }, { color: "black", value: "#000", selected: true }] // 将filtered转换为 { [value]: 对应对象 } 的映射 const filteredValueMap = _.keyBy(filtered, 'value'); // 遍历data,判断当前项的value是否在映射中 data.forEach(item => { item.selected = !!filteredValueMap[item.value]; }); console.log(data);
方案2:返回新数组(无副作用,函数式风格)
如果不想修改原数组,用_.map和_.includes组合生成新数组:
const _ = require('lodash'); const data = [{ color: "red", value: "#f00", selected: true }, { color: "green", value: "#0f0", selected: true }, { color: "blue", value: "#00f", selected: true }, { color: "cyan", value: "#0ff", selected: true }, { color: "magenta", value: "#f0f", selected: true }, { color: "yellow", value: "#ff0", selected: true }, { color: "black", value: "#000", selected: true } ] const filtered = [{ color: "magenta", value: "#f0f", selected: true }, { color: "green", value: "#0f0", selected: true }, { color: "black", value: "#000", selected: true }] // 提取filtered的value数组 const filteredValues = _.map(filtered, 'value'); // 生成新数组,不修改原数据 const newData = _.map(data, item => ({ ...item, selected: _.includes(filteredValues, item.value) })); console.log(newData);
总结
- 原生JS方案用
Set优化查找效率,无需额外依赖,适合轻量场景 - Lodash方案代码更简洁可读性更高,如果项目已引入Lodash非常推荐使用
- 如果要避免修改原数组的副作用,优先选择返回新数组的实现方式
内容的提问来源于stack exchange,提问作者arunmmanoharan
相关产品推荐
相关产品推荐

