原数据

        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. VScode 中golang 基准测试 go test -bench .

    目的:基准测试的主要目的是比较不同实现方式之间的性能差异,找出性能瓶颈. 1 准备以_test.go结尾文件和导入testing包 在命名文件时需要让文件必须以_test结尾,在文件中导入testin ...

  2. 自定义javascript中call、bind、apply方法

    call.bind.apply都是Function原型上的方法,用于改变this的指向 自定义函数 js中的call.bind.apply是用c++代码实现的,我们这里使用js代码做一个模式,没有把所 ...

  3. 从零玩转系列之微信支付实战PC端项目构建+页面基础搭建 | 技术创作特训营第一期

    一.前言 欢迎来到本期的博客!在这篇文章中,我们将带您深入了解前端开发领域中的一个热门话题: 如何使用 Vue 3 和 Vite 构建前端项目.随着现代 Web 应用程序的需求不断演进, 选择适当的工 ...

  4. Go 并发编程 - 并发安全(二)

    什么是并发安全 并发情况下,多个线程或协程会同时操作同一个资源,例如变量.数据结构.文件等.如果不保证并发安全,就可能导致数据竞争.脏读.脏写.死锁.活锁.饥饿等一系列并发问题,产生重大的安全隐患,比 ...

  5. 微信小程序2--WXML与WXSS

    编辑WXML文件 我们在开发者工具里打开之前修改的模板小程序home文件夹下的home.wxml,里面有如下代码 <!--pages/home/home.wxml--> <text& ...

  6. 发现了一个可以免费下载jar包的网站,所有jar包都有

    苦苦找不到项目所需要的jar包?发现了一个可以免费下载jar包的网站: https://jar-download.com/ 非常好用. 每个JAR文件都将从官方Maven存储库下载.通过下载所有Mav ...

  7. freeswitch sofia协议栈调试

    概述 freeswitch是一款简单好用的VOIP开源软交换平台. fs内部使用sofia的sip协议栈,本文介绍如何调试跟踪sofia协议栈. 环境 centos:CentOS  release 7 ...

  8. 关于.Net 6.0 在Linux ,Docker容器中,不安装任何依赖就生成图形验证码!!!!!!!!!!!

    在.Net Framework时代,我们生成验证码大多都是用System.Drawing. 在.Net 6中使用也是没有问题的. 但是,System.Drawing却依赖于Windows GDI+. ...

  9. Codechef - N Triplets(构造+观察)

    题目大意   对于一个正整数N,需要找到三个不同的数字A,B,C,使得三个数当中任意两个数字相乘都是N的约数,另外还要使得A,B,C三个数字乘积是N的整数倍数.最后输出三个数字(如果有多种组合,输出任 ...

  10. 解密网络通信的关键技术(下):DNS、ARP、DHCP和NAT,你了解多少?

    引言 在上一章中,我们详细介绍了域名系统(DNS)和地址解析协议(ARP)的工作原理,从而对域名解析和介质访问控制(MAC)地址寻址有了更深入的了解.在今天的章节中,我们将继续探讨动态主机配置协议(D ...