原数据

        let adreeJson = [
{id: 1, name: '陕西省', pid: 0},
{id: 2, name: '山西省', pid: 0},
{id: 3, name: '广东省', pid: 0},
{id: 4, name: '西安市', pid: 1},
{id: 5, name: '宝鸡市', pid: 1},
{id: 6, name: '莲湖区', pid: 4},
{id: 7, name: '雁塔区', pid: 4},
{id: 8, name: '深圳市', pid: 3},
{id: 9, name: '宝安区', pid: 8},
]

需解析成:

        let adressTree = [
{
id: 1, name: '陕西省', pid: 0,
child: [
{
id: 4, name: '西安市', pid: 1,
child: [
{id: 6, name: '莲湖区', pid: 4},
{id: 7, name: '雁塔区', pid: 4},
]
},
{
id: 5, name: '宝鸡市', pid: 1
},
]
},
{
id: 2, name: '山西省', pid: 0,
child: []
},
{
id: 3, name: '广东省', pid: 0,
child: [
{
id: 8, name: '深圳市', pid: 3,
child: [
{id: 9, name: '宝安区', pid: 8}
]
}
]
},
]

方法一:

先获取顶级节点,然后再通过递归获取其子节点

        function getTop(arry) {
return arry.filter(item => item.id == item.pid || item.pid == 0)
} function getChild(pArry, arry) {
pArry.forEach(idt => {
idt.child = arry.filter(item => idt.id == item.pid)
if ((idt.child).length > 0) {
getChild(idt.child, arry)
}
})
return pArry
} let topTree = getTop(adreeJson)
console.log(getChild(topTree, adreeJson))

方法二:

也是先获取父节点,然后再递归得到子节点

        //获取顶级节点
function getParent(arry, id) {
var newArry = new Array();
for (let i in arry) {
if (arry[i].pid == id)
newArry.push(arry[i]);
}
return newArry;
} function getTree(arrys, id) {
//深拷贝,否则会影响原数组
let arry = JSON.parse(JSON.stringify(arrys))
let childArry = getParent(arry, id);
if (childArry.length > 0) {
for (let i in childArry) {
//递归得到每个父节点的子节点
let _c_c_a = getTree(arry, childArry[i].id);
_c_c_a.length > 0 ? childArry[i].child = _c_c_a : childArry[i].child = []
}
}
return childArry
} console.log(getTree(adreeJson, 0))

方法三:

        /*通过定义map,key为当前对象id,value为该对象
遍历集合,得到对象顶级节点放到集合中返回
不是顶级的就是当前对象得子节点,将对象放到该节点下*/
function toTree(nodes) {
let result = []
//如果值是 Array,则为true; 否则为false。
if (!Array.isArray(nodes)) {
return result
}
//深拷贝,否则会影响原数组
let node = JSON.parse(JSON.stringify(nodes))
//根据父节点进行拼接子节点,
node.forEach(item => delete item.child)//已经有的话就删掉
//把每一项的引用放入map对象里
let map = {}
node.forEach(item => map[item.id] = item)
let newNode = []
node.forEach(dt => {
let parents = map[dt.pid]
if (parents) {
//如果 map[dt.pid] 有值 则 parents 为 dt 的父级
//判断 parents 里有无child 如果没有则创建 如果有则直接把 dt push到child里
((parents.child) || (parents.child = [])).push(dt)
//等同于:
// if (!parents.child) {
// parents.child = []
// }
// (parents.child).push(dt)
} else {
newNode.push(dt)
}
})
return newNode
} console.log(toTree(adreeJson))

参考:js将数组对象转化为树形结构

方法四:

        var flatToTree = flats => {
flats.forEach(item => {
var index = flats.findIndex(item1 => item1.id === item.pid)
if (index !== -1) {
//判断 flats[index] 里有无child 如果没有则创建 如果有则直接把 item push到child里
((flats[index].child) || (flats[index].child = [])).push(item)
//等同于:
// if (!flats[index].child) {
// flats[index].child = []
// }
// flats[index].child.push(item)
//或:
// flats[index].child = flats[index].child || []
// flats[index].child.push(item)
}
})
return flats.filter(dt => dt.pid === 0)//只获取父节点为0的值
}
console.log(flatToTree(adreeJson))

参考:id pid数据转为树形数据结构

js 通过id、pid遍历集合获得树结构的更多相关文章

  1. js 遍历集合删除元素

    js 遍历集合删除元素 /** * 有效的方式 - 改变下标,控制遍历 */ for (var i = 0; i < arr.length; i++) { if (...) { arr.spli ...

  2. connect by prior id= pid start with id='1' 树结构查询

    基础表创建: with temp as ( ' id, '' pid from dual union all ' pid from dual union all ' pid from dual uni ...

  3. jquery遍历集合&数组&标签

      jquery遍历集合&数组的两种方式 CreateTime--2017年4月24日08:31:49Author:Marydon 方法一: $(function(){ $("inp ...

  4. Lambda表达式遍历集合

    1.Collection Java 8 为Iterable接口新增了一个forEach(Consumer action)默认方法,该方法所需参数的类型是一个函数式接口,而Iterable接口是Coll ...

  5. Immutable.js – JavaScript 不可变数据集合

    不可变数据是指一旦创建就不能被修改的数据,使得应用开发更简单,允许使用函数式编程技术,比如惰性评估.Immutable JS 提供一个惰性 Sequence,允许高效的队列方法链,类似 map 和 f ...

  6. JAVA基础学习之final关键字、遍历集合、日期类对象的使用、Math类对象的使用、Runtime类对象的使用、时间对象Date(两个日期相减)(5)

    1.final关键字和.net中的const关键字一样,是常量的修饰符,但是final还可以修饰类.方法.写法规范:常量所有字母都大写,多个单词中间用 "_"连接. 2.遍历集合A ...

  7. java中遍历集合的三种方式

    第一种遍历集合的方式:将集合变为数组 package com.lw.List; import java.util.ArrayList; import java.util.List; import ja ...

  8. java8新特性,使用流遍历集合

    在这篇“Java 8新特性教程”系列文章中,我们会深入解释,并通过代码来展示,如何通过流来遍历集合,如何从集合和数组来创建流,以及怎么聚合流的值. 在之前的文章“遍历.过滤.处理集合及使用Lambda ...

  9. Java使用foreach遍历集合元素

    Java使用foreach遍历集合元素 1.实例源码 /** * @Title:ForEach.java * @Package:com.you.model * @Description:使用forea ...

  10. scala的多种集合的使用(3)之遍历集合的方法

    遍历集合的方法 1.用foreach循环遍历一个集合 foreach接收一个函数作为参数.定义的函数应该接收一个元素作为输入参数,然后不要返回任何的东西.输入的参数的类型应该匹配集合中的类型.随着fo ...

随机推荐

  1. chrome浏览器插件react devtools、redux devtools,无需安装、解压即可用

    react devtools用于调试react代码,可以查看到props.state的值,以及定义的hooks,而redux devtools可以追踪到action的派发.store的变化,两个都是r ...

  2. 【动画进阶】神奇的 3D 磨砂玻璃透视效果

    最近,群友分享了一个很有意思的效果: 原效果的网址:frosted-glass.该效果的几个核心点: 毛玻璃磨砂效果 卡片的 3D 旋转跟随效果 整体透明度和磨砂感.以及卡片的 3D 形态会随着用户移 ...

  3. 推荐一个高效解压缩工具 - XZ

    前情提要:前段时间搞某较大型项目的性能测试,使用的是Oracle数据库.压测阶段搞的业务基础数据和压测数据耗时耗力,想把数据导出,后续有类似项目,可以导入复用. 遇到问题:通过数据泵方式导出的数据库文 ...

  4. 问题排查:nginx的反向代理感觉失效了一样

    背景 最近,负责基础设施的同事,要对一批测试环境机器进行回收,回收就涉及到应用迁移,问题是整个过程一团乱.比如服务器A上一堆应用要调用服务器B上一堆服务,结果服务器B被回收了,然后服务器A上一堆应用报 ...

  5. 在 Visual Studio 2022 中使用文件对比

    在最新版本的 Visual Studio 2022 中,加入了新的功能特性--"文件对比". 在开发过程中,开发人员有时会需要比对文件差异,特别是代码文件,之前很多时候是借助版本控 ...

  6. 别再用 offset 和 limit 分页了,性能太差!

    不需要担心数据库性能优化问题的日子已经一去不复返了. 随着时代的进步,随着野心勃勃的企业想要变成下一个 Facebook,随着为机器学习预测收集尽可能多数据的想法的出现. 作为开发人员,我们要不断地打 ...

  7. 转载|QA|Pycharm一行代码太长如何换行?|Pycharm|工具相关

  8. 【krpano】密码插件

    密码插件可以在浏览场景或者执行action之前弹出密码输入框,要求用户输入密码.当密码输入成功了才可以进行下一步操作. 下载地址:http://pan.baidu.com/s/1gfOKKKF 给场景 ...

  9. AK、SK实现(双方API交互:签名及验证)

    参考:https://blog.csdn.net/yqwang75457/article/details/117815474 1.原理 AK/SK: AK:Access Key Id,用于标示用户. ...

  10. 【规范】SpringBoot接口返回结果及异常统一处理,这样封装才优雅

    前言 缘由 博友的需求就是我最大的动力 博友一说话,本狗笑哈哈.博友要我写啥,我就写啥. 特来一篇关于SpringBoot接口返回结果及异常统一处理,虽说封不封装都能用,但咱后端也得给前端小姐姐留个好 ...