python 树结构 转换 list_【Python】将有父子关系的一维数组转换成树形结构(多维)数据...

本文介绍了如何使用Python将具有父子关系的一维数组转换为树形结构的多维数据。讨论了避免循环引用的问题,并提供了多个实现方案,包括使用filter和递归函数的方法。代码示例展示了如何通过比较id和parentId属性构建树形结构。
摘要由CSDN通过智能技术生成

已知原有数据 :

var data=[

{ id: 40, parentId: 31, note: "的萨达是" },

{ id: 20, parentId: 11, note: "的萨达是" },

{ id: 22, parentId: 20, note: "dsadas" },

{ id: 12, parentId: null, note: "dsadasad萨达s" },

{ id: 11, parentId: undefined, note: "dqwds" },

{ id: 24, parentId: 22, note: "搜索" },

{ id: 34, parentId: 22, note: "搜索" }

]

需要考虑的问题 :

不更改源数据

避免循环引用, 即 a的parentId为b, b的parentId为a

发挥你的大脑, 来个最优解

回答

先来个函数注释 :

/**

* 将有父子关系的一维数组转换成树形结构(多维)数据

* console.log(JSON.stringify(setTreeData(data), null, 2));

* ============================================

* @param {*Array} data 需要遍历的一维数组

*/

再来具体的代码 :

function fnSetTreeData(data) {

var data = [...data];

var tree = data.filter((father) => {

var branchArr = data.filter((child) => {

if (father.id == child.parentId) child._hasParent = true;

return father.id == child.parentId;

// MARK 为什么这样写就报错 ?

// if (father.id == child.parentId) child._hasParent = true;

// return child._hasParent

});

if (branchArr.length > 0) father.children = branchArr;

return !father._hasParent;

});

// MARK 为什么在这里还得加一个过滤

tree = tree.filter((item) => {

return !item._hasParent;

})

return tree

}

console.log(JSON.stringify(fnSetTreeData(data), null, 2));

至于怎么解决 循环引用 的问题, 先用 sort 给数组排序后, 再在每次filter 中 计数++如何 ?

得给一个测试数据 :

var data = [

{ id: 40, parentId: 31, note: "的萨达是" },

{ id: 20, parentId: 11, note: "的萨达是" },

{ id: 22, parentId: 20, note: "dsadas" },

{ id: 12, parentId: null, note: "dsadasad萨达s" },

{ id: 11, parentId: undefined, note: "dqwds" },

{ id: 24, parentId: 22, note: "搜索" },

{ id: 34, parentId: 22, note: "搜索" }

];

const toTree =

(arr, pID) =>

arr

.filter(({ parentId }) => parentId == pID)

.map(a => ({

...a,

childers: toTree(arr.filter(({ parentId }) => parentId != pID), a.id)

}))

function listToTree(data) {

let arr = JSON.parse(JSON.stringify(data))

const listChildren = (obj, filter) => {

[arr, obj.children] = arr.reduce((res, val) => {

if (filter(val))

res[1].push(val)

else

res[0].push(val)

return res

}, [[],[]])

obj.children.forEach(val => {

if (arr.length)

listChildren(val, obj => obj.parentId === val.id)

})

}

const tree = {}

listChildren(tree, val => arr.findIndex(i => i.id === val.parentId) === -1)

return tree.children

}

先复制一份原数组 为了不循环引用和增加循环效率 每往tree里加个节点 从复制数组里删掉此节点

我是来学习的,

这样子写好像也是能实现的,但是不友好。希望各位提建议。

双层循环,外层循环的id匹配内层循环的parentId,相等的话内层循环的item直接插入外层循环item的childers中,

内层循环结束后外层循环判断自己的parentId是否匹配得到,匹配不到单独拎出来。

function setTreeData(arg) {

var data = [...arg];

var sort = [];

var parentIdArr = []

data.map((item, idx) => {

item.childers = [];

let pp = Object.assign({}, data)

data.map((subitem, subidx) => {

parentIdArr.push(subitem.id)

if (item.id === subitem.parentId) {

item.childers.push(subitem);

}

})

var obj = Object.assign({}, item);

parentIdArr = [...new Set(parentIdArr)]

if (item.parentId - 1 > 0) {

parentIdArr.indexOf(item.parentId) == -1 ? sort.push(item) : ""

} else {

sort.push(item)

}

})

return sort

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值