2 回答
TA贡献1886条经验 获得超2个赞
不要在回调中创建const p局部变量reduce,而是使用完成后可访问的变量reduce,以便您可以访问最后分配的对象以添加附加属性(或多个属性)。
所以改变:
const p = { path, children: r[path].result };
r.result.push(p);
到:
last = { path, children: r[path].result };
r.result.push(last);
并last在块的作用域中定义为局部变量for。完成后reduce,您可以使用Object.assign来改变“叶子”对象,添加额外的属性:
Object.assign(last, rest); // rest is whatever needs to be added.
所以你的代码可以修改如下:
const result = [];
const level = { result };
for (p of pathObjs) {
let last; // This will be the latest added object
let { path, ...rest } = p; // Extract the path and the other properties
path.split('/').reduce((r, path, i, {length}) => {
if (!r[path]) {
r[path] = { result: [] };
last = { path, children: r[path].result };
r.result.push(last);
}
return r[path];
}, level);
Object.assign(last, rest); // Extend with the extra properties.
}
TA贡献1757条经验 获得超7个赞
该解决方案重组了您的原始代码。主要区别在于路径列表是相反的,因此我们从叶节点而不是根开始。
有一个显式检查来查看我们是否位于第一个索引(我们可以假设它是叶子)。或者,如果您愿意,您可以检查是否result已定义,并依赖它而不是索引。
const pathObjects = [{ id: 1, path: "foo/bar/baz" }];
const result = [];
for (let { id, path } of pathObjects) {
const obj = path
.split("/")
.reverse()
.reduce((result, path, index) => {
const node = {
path,
children: result ? [result] : []
};
if (index === 0) {
node.id = id;
}
return node;
}, null);
result.push(obj);
}
console.log(result);
添加回答
举报