使用.reduce()时如何从deepSubtract结果集中排除空对象?
移除deepSubtract输出中的空对象
当前通过.reduce()实现的deepSubtract()方法可完成对象间的差值计算,但当两个对象数据完全匹配时,输出会残留空对象{},导致待审查数据冗余。需要调整方法逻辑,让最终结果自动剔除所有空对象。
原数据样本
const preMigration = { "100": { "line": { "machines": 1, "operators": 4 }, "profile": [ { "capacity": 0.8, "downtimeAllowance": 0.99 }, { "capacity": 0.95, "downtimeAllowance": 0.7 } ] }, "200": { "line": { "machines": 6, "operators": 12 }, "profile": [{ "capacity": 0.9, "downtimeAllowance": 0.85 }] }, "300": { "line": { "machines": 9, "operators": 3 }, "profile": [ { "capacity": 0.85, "downtimeAllowance": 0.71 }, { "capacity": 0.94, "downtimeAllowance": 0.97 } ] } } const postMigration = { "100": { "line": { "machines": 1, "operators": 0 }, "profile": [ { "capacity": 0.8, "downtimeAllowance": 0.99 }, { "capacity": 0.95, "downtimeAllowance": 0.7 } ] }, "200": { "line": { "machines": 6, "operators": 12 }, "profile": [{ "capacity": 0.9, "downtimeAllowance": 0.85 }] }, "300": { "line": { "machines": 9, "operators": 5 }, "profile": [ { "capacity": 0.85, "downtimeAllowance": 0.71 }, { "capacity": 0.96, "downtimeAllowance": 0.97 } ] } }
原deepSubtract方法
this.deepSubtract = (obj1, obj2) => { const uniqueKeys = [...new Set([...Object.keys(obj1), ...Object.keys(obj2)])]; const reduction = uniqueKeys.reduce((acc, key) => { if (typeof obj2[key] === 'object') { acc[key] = this.deepSubtract(obj1[key], obj2[key]); } else { if (obj1[key] !== obj2[key]) acc[key] = obj1[key] - obj2[key] } return acc; }, {}); return reduction; }
期望输出
{ "100": { "line": { "operators": -4 } }, "300": { "line": { "operators": 2 }, "profile": { "1": { "capacity": 0.020000000000000018 } } } }
修改后的解决方案
核心思路是在递归计算后,检查当前层级的结果是否为空对象/空数组,仅保留非空的结果到最终输出中。添加一个工具函数判断空值,同时调整reduce逻辑,避免空对象被加入累加器。
修改后的完整代码
// 工具函数:判断是否为空对象/空数组 const isEmpty = (value) => { if (Array.isArray(value)) return value.length === 0; if (typeof value === 'object' && value !== null) return Object.keys(value).length === 0; return false; } this.deepSubtract = (obj1, obj2) => { const uniqueKeys = [...new Set([...Object.keys(obj1), ...Object.keys(obj2)])]; const reduction = uniqueKeys.reduce((acc, key) => { // 处理数组/对象的递归计算 if (typeof obj2[key] === 'object' && obj2[key] !== null) { const subResult = this.deepSubtract(obj1[key], obj2[key]); // 仅当子结果非空时,才添加到累加器 if (!isEmpty(subResult)) { acc[key] = subResult; } } else { // 处理非对象类型,仅当值不同时添加差值 if (obj1[key] !== obj2[key]) { acc[key] = obj1[key] - obj2[key]; } } return acc; }, {}); // 返回前检查当前层级结果是否为空,空则返回undefined(不会被上层保留) return isEmpty(reduction) ? undefined : reduction; } const dataValidation = this.deepSubtract(postMigration, preMigration); console.log(JSON.stringify(dataValidation, null, 4));
关键修改点
- 添加
isEmpty工具函数:统一判断空对象、空数组的逻辑,避免重复代码 - 递归后过滤空结果:子层级计算完成后,先判断是否为空,非空才加入当前层级的结果
- 顶层结果过滤:当前层级计算完成后,若为空则返回
undefined,上层递归会自动忽略该值,不会生成空对象
运行修改后的代码,输出将与期望结果完全一致,自动剔除所有空对象,仅保留有差值的节点。
内容的提问来源于stack exchange,提问作者knot22
相关产品推荐
相关产品推荐

