把下面数据,转化成树形结构
各位大佬,帮忙看看,如何处理
let ary = [ { 1: '一级标题1' },
{ 2: '二级标题1' },
{ 2: '二级标题2' },
{ 3: '三级标题1' },
{ 3: '三级标题2' },
{ 4: '四级标题' },
{ 5: '五级标题' }
]
转化成如下
let tree = [ {
h: '1',
name: '一级标题1',
children: [
{
h: '2',
name: '二级标题1',
children: []
},
{
h: '2',
name: '二级标题2',
children: [
{
h: '3',
name: '三级标题1',
children: []
},
{
h: '3',
name: '三级标题2',
children: [
{
h: '4',
name: '四级标题',
children: [
{
h: '5',
name: '五级标题',
children: []
}
]
},
]
},
]
}
]
}
]
回答:
- 获取当前这段html的转化成dom
- 循环获取h标签
回答:
const ary = [ { 1: '一级标题1' },
{ 2: '二级标题1' },
{ 2: '二级标题2' },
{ 3: '三级标题1' },
{ 3: '三级标题2' },
{ 4: '四级标题' },
{ 5: '五级标题' }
]
const normalizeNode = (obj) => {
let key
for (let i in obj) {
key = i
break;
}
const value = obj[key]
return {
h: String(key),
name: value,
children: []
}
}
const transform = (ary) => {
// 存入已经转化后的节点,初始化时推入假的一个根节点
const stack = [{
h: -Infinity,
name: 'root',
children: []
}]
// 遍历
for (let i = 0, l = ary.length; i < l; i++) {
const node = normalizeNode(ary[i])
let j = stack.length - 1
// 需要与前面的节点逐一比较,找到第一个比当前节点小的插入并入栈
while (j >= 0) {
const top = stack[j]
if (node.h > top.h) {
top.children.push(node)
stack.push(node)
break
}
j--;
}
}
return stack[0].children
}
console.log(JSON.stringify(transform(ary), null, 2))
回答:
function transform(arr) { var ret = [];
for (var i = 0; i < arr.length; ++i) {
for (var key in arr[i]) {
ret[i] = {
h: key,
name: arr[i][key],
children: []
};
break;
}
}
ret.sort(function(a, b) {
return a.h - b.h || a.name.localeCompare(b.name);
});
for (var i = ret.length - 1; i-- > 0;) {
if (ret[i].h !== ret[i + 1].h) {
ret[i].children = ret.splice(i + 1);
}
}
return ret;
}
console.dir(transform(ary));
回答:
这个思路的关键在于找到当前节点和之前的处理状态(处理的所有节点)之间的关系。原数据应该是按文章标题序给的,所以一定会先处理父节点再处理子节点,而且处理过的节点再回到父级之后,这个子级节点就一定不会再现。
另外需要注意的一点,下面这个算法不能处理跳级,也就是一级标题下直接接三级标题的情况。如果确实需要处理跳级的情况,需要再缓存一个上次处理的级别序号来辅助判断,并对跳过的级别进行一些特殊处理。
let ary = [ { 1: "一级标题1" },
{ 2: "二级标题1" },
{ 3: "三级标题5" }, // 这里补了一条数据
{ 2: "二级标题2" },
{ 3: "三级标题1" },
{ 3: "三级标题2" },
{ 4: "四级标题" },
{ 5: "五级标题" }
];
function transform(data) {
// 加个虚根,方便所有子节点按同样的逻辑处理
const processing = [{ h: "0", name: "v-root", children: [] }];
data.forEach(it => {
// { 2: "xxx" } 的对象很神奇,先转成目标对象结构
const [h, name] = Object.entries(it)[0];
const node = { h, name, children: [] };
// h 取整就是当前 level(有效数据 level 从 1 开始,虚根 level 是 0
const level = ~~h;
// 当前行进到 processing[level] 节点(后面的节点会根据当前节点来进行)
processing[level] = node;
// 把当前节点加到父级当前节点中(这里理解不了可以模拟一下处理过程)
processing[level - 1].children.push(node);
});
// 返回虚根的 children 就是树的根
return processing[0].children;
}
const result = transform(ary);
console.log(JSON.stringify(result, null, 2));
以上是 把下面数据,转化成树形结构 的全部内容, 来源链接: utcz.com/p/937303.html