JavaScript:将线性JSON数组转换为深度未知的树结构
JavaScript: Convert linear JSON array into tree structure with unknown depth
我有一个JavaScript数组,如下所示:
[{
name:'a'
level:1
},{
name:'b'
level:2
},{
name:'c'
level:3
},{
name:'d'
level:2
},{
name:'e'
level:1
},{
name:'f'
level:2
},{
name:'g'
level:2
},{
name: 'f',
level: 1
}
]
我需要将其转换为基于对象的level
属性的树结构
[{
name: 'a'
level: 1
children: [{
name: 'b'
level: 2,
children: [{
name: 'c',
level: 3
}]
}, {
name: 'd'
level: 2
}]
}, {
name: 'e'
level: 1,
children: [{
name: 'f'
level: 2
}, {
name: 'g'
level: 2
}]
}, {
name: 'f',
level: 1
}]
我试过写很多函数,尝试过很多方法,但都失败了。我意识到,这只能通过编写递归函数来实现。请帮忙。
注:液位深度不限于3,未知
下面是一个快速入门:
var res = convert(a);
console.log(res);
function convert(arr) {
return treeify(splitToSegments(arr));
}
function splitToSegments(arr) {
var ret = [];
var accum, segment;
arr.forEach(function(o) {
if (o.level === 1) {
accum = true;
if (segment && segment.length) {
ret.push(segment);
}
segment = [o];
} else if (accum) {
segment.push(o);
}
});
if (segment && segment.length) {
ret.push(segment);
}
return ret;
}
function treeify(arr) {
return arr.map(function(o) {
return o.reduce(function(a, b) {
var lastChild;
a.children = a.children || [];
if (a.level + 1 === b.level) {
a.children.push(b);
} else {
lastChild = a.children[a.children.length - 1];
lastChild.children = lastChild.children || [];
lastChild.children.push(b);
}
return a;
});
});
}
注意,treeify
可能需要一些额外的逻辑来处理兄弟,但它应该是一个okish起点。
我遇到了完全相同的问题,这就是我的解决方案:
function constructTree (flatList) {
const tree = [];
const clonedList = cloneDeep(flatList);
let root = {};
function append (child, parent) {
if (Array.isArray(parent.children)) {
parent.children.push(child);
} else {
parent.children = [child];
}
return parent;
}
function appendParentAdjacentNode (level, node, nodes) {
if (level === 0) {
nodes.push(node);
return node;
}
while (level > 0) {
return appendParentAdjacentNode(level - 1, node, nodes[0].children);
}
return node;
}
let parent;
for (let i = 0; i < clonedList.length; i++) {
const currentNode = clonedList[i];
const previousNode = clonedList[i - 1];
const isRoot = currentNode.level === 0;
if (isRoot) {
root = currentNode;
tree.push(root);
continue;
}
const isChild = currentNode.level > previousNode.level;
const isSibling = currentNode.level === previousNode.level;
const isParentAdjacent = currentNode.level < previousNode.level;
if (isChild) {
parent = previousNode;
}
if (isChild || isSibling) {
append(currentNode, parent);
}
if (isParentAdjacent) {
appendParentAdjacentNode(currentNode.level - 1, currentNode, root.children);
}
}
return tree;
}
简要说明:
- 为了保持函数的纯粹性,我在操作输入(flatList)之前先克隆它
- 该解决方案基于这样的假设,即如果当前节点的级别更高,则前一个节点是当前节点的父节点
- A";父相邻节点";只是层次结构中较高的节点,但不是当前节点的直接父节点(我认为它是叔叔/阿姨)。如果你有更好的名字,请分享你的建议
- 在我的场景中,根节点的级别为0。然而,在提问者的场景中,根节点的级别为1
- 我正在使用递归来附加父相邻节点
相关文章:
- 在不知道深度或父属性的情况下从对象中删除属性
- 递归深度比较
- 如何对映射插件创建的敲除对象进行深度复制
- 对广告服务器的未知信标调用
- 3d上的深度比例错误
- Axios spread()具有未知数量的回调参数
- 将对象从另一个不可变的Map分配给Map是否意味着深度克隆
- 反汇编的javascript jit代码调用未知函数
- 未知”<#"构造
- BatmanJS:深度嵌套路由
- Chai深度包含了对嵌套对象的断言
- Safari 5.1.7下载文件名未知的csv文件
- JavaScript:将线性JSON数组转换为深度未知的树结构
- 在 JavaScript 中的对象中设置具有未知深度的属性值
- 如何获得未知JSON层次结构的总深度
- 我怎么能找到关键在JavaScript对象时,他的深度是未知的
- 编写一个递归函数,迭代嵌套循环的深度未知
- 迭代未知深度的对象
- Javascript-在深度嵌套对象上迭代并更改某些未知值
- 用jQuery从未知深度的嵌套JSON构建级联下拉列表