写点什么

JavaScript 中删除树形结构数据里的节点

用户头像
brave heart
关注
发布于: 2020 年 06 月 17 日
JavaScript中删除树形结构数据里的节点

前言

在项目中有个需求,需要删除树形结构数据里children为空的节点,意思就是,最深层的children为空,全删掉之后,外层的children也变成空了,继续删除,直至所有children为空的节点都删除。

实现过程

一开始我直接使用forEach()方法,遍历树形结构数据treeData,然后判断info.children为空,就删除这个info,如果不为空,就递归,代码如下所示:

deleteGroup(treeData) {
function traversal(data) {
data.forEach(info => {
if (info.children) {
if (info.children.length === 0) {
const index = data.findIndex(item => info.id === item.id)
data.splice(index, 1)
}
if (info.children.length > 0) {
traversal(info.children)
}
}
})
}
traversal(treeData)
}

遇到的问题

按照这个思路实现,并没有什么问题,treeData里确实也删除了children的节点,但总会出现没有删除干净,有部分children为空的节点并没有被删除,这个问题一下子让我怀疑是不是代码哪里写错了,亦或是使用splice方法有问题?之前学过几节宫文学老师的《编译原理之美》,照着里面讲的编译器执行顺序,画图探索一番,还是没找到问题在哪里。在这里花了好多时间,感觉很不值得,就请教了同事,因为人本身会有看问题上面的局限性,多多交流,很容易得到新的思路,就好像《少年包青天》里唱的那句歌词一样,“一些漫不经心的说话,将我疑惑解开。”

后来,经过研究,才发现是在循环删除treeData中的节点之后,出现了异常,treeData的索引发生了变化,才造成了这个问题。我一下子幡然醒悟,其实早些年,在学习Java时,就遇到过这个问题,对在for中删除数组的元素,都要注意索引i--,也就知道了问题出在哪里了。

实现代码

因为要注意索引的变化,就直接使用普通for循环了,代码如下所示:

deleteGroup(treeData) {
function traversal(data) {
for (let i = 0; i < data.length; i++) {
const info = data[i]
if (info.children) {
if (info.children.length > 0) {
traversal(info.children)
}
if (info.children.length === 0) {
const index = data.findIndex(item => info.id === item.id)
data.splice(index, 1)
i--
}
}
}
}
traversal(treeData)
}

写在最后

不管在工作还是生活中,在解决难题时,当然需要自己独立思考一番,也不能什么难题都做伸手党,想要不劳而获是很不好的,但也要知道给自己设定一个时间期限,比如半个小时一个小时之类,这个难题没有在规定的时间里解决掉,就要知道借力了,死磕与借力要做到平衡吧,就比如这个问题,一个很基本的细节没注意到,让我浪费了那么多时间,太不划算了。



发布于: 2020 年 06 月 17 日阅读数: 153
用户头像

brave heart

关注

唯一不变的是变化本身。 2018.04.17 加入

🗡 她只唱只想这首止战之殇。

评论

发布
暂无评论
JavaScript中删除树形结构数据里的节点