原数据

        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. 如何用IoT边缘连接器实现云端应用控制PLC?

    本文分享自华为云社区<数字工厂深入浅出系列(十):IoT边缘连接器实现云端应用控制PLC>,作者: 云起MAE. 通过IoT云平台和边缘计算的技术设施,工厂可以将PLC等OT过程制造控制器 ...

  2. c++中unique_ptr 的使用和理解

    unique_ptr 的使用 std::unique_ptr是c++11起引入的智能指针,为什么必须要在c++11起才有该特性,主要还是c++11增加了move语义,否则无法对对象的所有权进行传递. ...

  3. 解决使用sqlalchemy时MySQL密码含有特殊字符问题

    前言 当MySQL密码中含有特殊字符时,使用sqlalchemy大概率连不上,这时候就需要from urllib.parse import quote_plus as urlquote. 示例代码 f ...

  4. .NET周刊【8月第1期 2023-08-06】

    国内文章 NativeBuferring,一种零分配的数据类型(上篇) https://www.cnblogs.com/artech/p/17586781.html 之前一个项目涉及到针对海量(千万级 ...

  5. Mybatis-Plus+Nacos+Dubbo进行远程RPC调用保姆级教程

    默认你已经看过我之前的教程了,并且拥有上个教程完成的项目, 之前的教程 https://www.cnblogs.com/leafstar/p/17638782.html 1.在bank1的pom文件中 ...

  6. 用ChatGPT三分钟免费做出数字人视频- 提升自媒体魅力

    本教程收集于:AIGC从入门到精通教程汇总 操作指引 ChatGPT产生文案=>腾讯智影数字人播报=>粘贴文案=>导出视频. 说明:部分资源只有会员才能用~,非会员可生成5分钟视频. ...

  7. XV6中的锁:MIT6.s081/6.828 lectrue10:Locking 以及 Lab8 locks Part1 心得

    这节课程的内容是锁(本节只讨论最基础的锁).其实锁本身就是一个很简单的概念,这里的简单包括 3 点: 概念简单,和实际生活中的锁可以类比,不像学习虚拟内存时,现实世界中几乎没有可以类比的对象,所以即使 ...

  8. QA|workon env后没有进入虚拟环境,但也没有报错,但cmd可以|Python虚拟环境

    问题:pycharm的terminal执行workon env后没有进入虚拟环境,但也没有报错 但cmd可以 原因:因为pycharm的terminal用的是powershell,更改为cmd,重新打 ...

  9. VMware上安装Centos7

    一.下载Centos镜像 国内镜像网站: 清华大学:清华大学开源软件镜像站 | Tsinghua Open Source Mirror 阿里云:阿里巴巴开源镜像站-OPSX镜像站-阿里云开发者社区 ( ...

  10. sqlite/mysql 省市县三级联动

    这个是sqlite的, 改下表结构, 就可以给mysql用了 CREATE TABLE ProvinceCityZone ( _id INTEGER PRIMARY KEY AUTOINCREMENT ...