如何在JavaScript中将深度嵌套对象聚合到单个键中?
对象属性数组聚合方案
你需要将多个子对象中的动态属性数组合并去重,聚合到all对象中,lodash的merge方法仅处理父级键的合并,无法实现深层数组的去重聚合,这里提供两种可行方案:
原生JavaScript实现
const sourceObj = { "op1": { "color": ["red", "yellow"], "size": [1, 3] }, "op2": { "color": ["black", "green"], "size": [1, 2] }, "op3": { "color": ["black"] } }; const result = { all: {} }; // 遍历所有子对象 Object.values(sourceObj).forEach(subObj => { // 遍历子对象的每个属性键值对 Object.entries(subObj).forEach(([propKey, propValues]) => { // 初始化目标属性数组 if (!result.all[propKey]) { result.all[propKey] = []; } // 去重添加元素 propValues.forEach(val => { if (!result.all[propKey].includes(val)) { result.all[propKey].push(val); } }); }); }); console.log(result);
这段代码通过两层遍历,逐个处理每个子对象的属性:先检查目标all对象中是否存在对应属性,不存在则初始化空数组;再遍历当前属性的数组元素,去重后添加到目标数组中,完全适配动态属性的场景。
Lodash实现(使用mergeWith自定义合并逻辑)
const _ = require('lodash'); const sourceObj = { "op1": { "color": ["red", "yellow"], "size": [1, 3] }, "op2": { "color": ["black", "green"], "size": [1, 2] }, "op3": { "color": ["black"] } }; const result = _.mergeWith( { all: {} }, // 将每个子对象包装为{all: 子对象}的结构,统一合并到目标的all属性下 ...Object.values(sourceObj).map(subObj => ({ all: subObj })), // 自定义合并规则 (targetVal, sourceVal) => { // 若合并的是数组,则合并后去重 if (_.isArray(targetVal)) { return _.uniq([...targetVal, ...sourceVal]); } } ); console.log(result);
利用mergeWith的自定义回调函数,针对数组类型的属性,将目标数组和源数组合并后用uniq去重,解决了原生merge无法处理深层数组聚合的问题。
内容的提问来源于stack exchange,提问作者twobo
相关产品推荐
相关产品推荐

