我有一棵嵌套对象的树(3层,分别代表建筑物,地板,房间)。叶节点包含房间区域。我想在给定级别(动态提供)下总结该区域,而无需更改源数据。
const data = {
building1: {
floor1: {
room1: {
area: 0.1,
},
room2: {
area: 0.2,
}
},
floor2: {
room1: {
area: 0.3,
},
room2: {
area: 0.4,
}
}
},
building2: {
floor1: {
room1: {
area: 0.15,
},
room2: {
area: 0.25,
}
},
floor2: {
room1: {
area: 0.35,
},
room2: {
area: 0.45,
}
}
},
level: 3
};
例如,我需要一个1级(建筑物级)摘要来返回看起来像这样的新对象:
{
building1: {
area: 1
},
building2: {
area: 1.2
}
}
我希望能够获得一个像这样的2级摘要:
{
building1: {
floor1: {
area: 0.3
},
floor2: {
area: 0.7
}
},
building2: {
floor1: {
area: 0.4
},
floor2: {
area: 0.8
}
}
}
累加只是简单的算术和。我可以获取树中任何节点的摘要(组合区域),但是不确定如何克隆源数据并用摘要替换所需级别的数据。
const addAreas = (op1, op2) => ({
area: op1.area + op2.area
})
const traverseNodeToArea = node => {
return Object.entries(node).map(([key, val]) =>
val.hasOwnProperty('area')
? val
: traverseNodeToArea (val)
).reduce(addAreas,{
area: 0
});
};
如果有帮助,乐意使用lodash。我确信必须有一个简单的解决方案,但我看不到。
(traverseNodeToArea
基于this answer)
答案 0 :(得分:2)
您可以使用级别计数器,如果级别为零,则获取剩余嵌套区域的总和。
function getSummary(object, level) {
const getSumOfArea = object => Object.entries(object).reduce((r, [k, v]) => r + (k === 'area' ? v : getSumOfArea(v)), 0);
if (!object || typeof object !== 'object')
return object;
if (level)
return Object.assign(...Object.entries(object).map(([k, v]) => ({ [k]: getSummary(v, level - 1) })));
return { area: getSumOfArea(object) };
}
const data = { building1: { floor1: { room1: { area: 0.1, }, room2: { area: 0.2, } }, floor2: { room1: { area: 0.3, }, room2: { area: 0.4, } } }, building2: { floor1: { room1: { area: 0.15, }, room2: { area: 0.25, } }, floor2: { room1: { area: 0.35, }, room2: { area: 0.45, } } }, level: 3 };
console.log(getSummary(data, 0));
console.log(getSummary(data, 1));
console.log(getSummary(data, 2));
console.log(getSummary(data, 3));
.as-console-wrapper { max-height: 100% !important; top: 0; }