JavaScript如何基于另一嵌套对象数组对现有数组嵌套对象增删改
问题描述
我需要基于另一个数组中的对象,对现有数组内的嵌套对象进行新增、更新或删除操作。例如:我希望根据update数组更新date -> gte的取值,同时保留entry -> eq的配置,还要新增date -> lte配置。
我尝试使用如下代码片段实现需求,但最终输出的结果数据量膨胀,且存在错误的键值对:
const existing = [ { date: { gte: '2021-01-01' } }, { entry: { eq: 1 } }, { keep: { eq: 100 } }, ]; const update = [ { date: { gte: '2021-02-01' } }, { date: { lte: '2021-12-31' } }, ]; const outcome = []; update.forEach((el) => { existing.forEach(elem => { Object.entries(elem).forEach(([k, v]) => { Object.entries(el).forEach(([key, value]) => { if (k === key && Object.keys(v).sort().toString() === Object.keys(value).sort().toString()) { outcome.push(el) } else { outcome.push(elem) } }); }); }) }); console.log(outcome); // 预期输出结果 // [ // { date: { gte: '2021-02-01' } }, // { entry: { eq: 1 }}, // { keep: { eq: 100 } }, // { date: { lte: '2021-12-31' } } // ] // 当前实际输出结果 // [ // { date: { gte: '2021-02-01' } }, // { entry: { eq: 1 } }, // { keep: { eq: 100 } }, // { date: { gte: '2021-01-01' } }, // { entry: { eq: 1 } }, // { keep: { eq: 100 } } // ]
原因分析
原代码嵌套了多层循环,每次匹配失败都会把原有元素重复推入结果数组,最终导致数据量翻倍、旧数据残留。
解决思路
先给每个配置项生成唯一标识(格式为顶级键-嵌套运算符键,比如date-gte、entry-eq),用映射表存储数据,先导入原有配置,再用更新配置覆盖/新增,最后转成数组即可。
可运行代码
const existing = [ { date: { gte: '2021-01-01' } }, { entry: { eq: 1 } }, { keep: { eq: 100 } }, ]; const update = [ { date: { gte: '2021-02-01' } }, { date: { lte: '2021-12-31' } }, ]; // 生成配置项的唯一标识 const getKey = (item) => { const [topKey, nestedObj] = Object.entries(item)[0] const [nestedKey] = Object.keys(nestedObj) return `${topKey}-${nestedKey}` } // 初始化映射表 const configMap = {} // 导入原有配置 existing.forEach(item => { configMap[getKey(item)] = item }) // 用更新配置覆盖/新增 update.forEach(item => { configMap[getKey(item)] = item }) // 转成数组即为最终结果 const outcome = Object.values(configMap) console.log(outcome)
输出结果
[ { date: { gte: '2021-02-01' } }, { entry: { eq: 1 } }, { keep: { eq: 100 } }, { date: { lte: '2021-12-31' } } ]
完全符合预期要求。
内容的提问来源于stack exchange,提问作者proph3t
相关产品推荐
相关产品推荐

