js 通过id、pid遍历集合获得树结构
原数据
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))
方法四:
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))
js 通过id、pid遍历集合获得树结构的更多相关文章
- js 遍历集合删除元素
js 遍历集合删除元素 /** * 有效的方式 - 改变下标,控制遍历 */ for (var i = 0; i < arr.length; i++) { if (...) { arr.spli ...
- 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 ...
- jquery遍历集合&数组&标签
jquery遍历集合&数组的两种方式 CreateTime--2017年4月24日08:31:49Author:Marydon 方法一: $(function(){ $("inp ...
- Lambda表达式遍历集合
1.Collection Java 8 为Iterable接口新增了一个forEach(Consumer action)默认方法,该方法所需参数的类型是一个函数式接口,而Iterable接口是Coll ...
- Immutable.js – JavaScript 不可变数据集合
不可变数据是指一旦创建就不能被修改的数据,使得应用开发更简单,允许使用函数式编程技术,比如惰性评估.Immutable JS 提供一个惰性 Sequence,允许高效的队列方法链,类似 map 和 f ...
- JAVA基础学习之final关键字、遍历集合、日期类对象的使用、Math类对象的使用、Runtime类对象的使用、时间对象Date(两个日期相减)(5)
1.final关键字和.net中的const关键字一样,是常量的修饰符,但是final还可以修饰类.方法.写法规范:常量所有字母都大写,多个单词中间用 "_"连接. 2.遍历集合A ...
- java中遍历集合的三种方式
第一种遍历集合的方式:将集合变为数组 package com.lw.List; import java.util.ArrayList; import java.util.List; import ja ...
- java8新特性,使用流遍历集合
在这篇“Java 8新特性教程”系列文章中,我们会深入解释,并通过代码来展示,如何通过流来遍历集合,如何从集合和数组来创建流,以及怎么聚合流的值. 在之前的文章“遍历.过滤.处理集合及使用Lambda ...
- Java使用foreach遍历集合元素
Java使用foreach遍历集合元素 1.实例源码 /** * @Title:ForEach.java * @Package:com.you.model * @Description:使用forea ...
- scala的多种集合的使用(3)之遍历集合的方法
遍历集合的方法 1.用foreach循环遍历一个集合 foreach接收一个函数作为参数.定义的函数应该接收一个元素作为输入参数,然后不要返回任何的东西.输入的参数的类型应该匹配集合中的类型.随着fo ...
随机推荐
- 如何用IoT边缘连接器实现云端应用控制PLC?
本文分享自华为云社区<数字工厂深入浅出系列(十):IoT边缘连接器实现云端应用控制PLC>,作者: 云起MAE. 通过IoT云平台和边缘计算的技术设施,工厂可以将PLC等OT过程制造控制器 ...
- c++中unique_ptr 的使用和理解
unique_ptr 的使用 std::unique_ptr是c++11起引入的智能指针,为什么必须要在c++11起才有该特性,主要还是c++11增加了move语义,否则无法对对象的所有权进行传递. ...
- 解决使用sqlalchemy时MySQL密码含有特殊字符问题
前言 当MySQL密码中含有特殊字符时,使用sqlalchemy大概率连不上,这时候就需要from urllib.parse import quote_plus as urlquote. 示例代码 f ...
- .NET周刊【8月第1期 2023-08-06】
国内文章 NativeBuferring,一种零分配的数据类型(上篇) https://www.cnblogs.com/artech/p/17586781.html 之前一个项目涉及到针对海量(千万级 ...
- Mybatis-Plus+Nacos+Dubbo进行远程RPC调用保姆级教程
默认你已经看过我之前的教程了,并且拥有上个教程完成的项目, 之前的教程 https://www.cnblogs.com/leafstar/p/17638782.html 1.在bank1的pom文件中 ...
- 用ChatGPT三分钟免费做出数字人视频- 提升自媒体魅力
本教程收集于:AIGC从入门到精通教程汇总 操作指引 ChatGPT产生文案=>腾讯智影数字人播报=>粘贴文案=>导出视频. 说明:部分资源只有会员才能用~,非会员可生成5分钟视频. ...
- XV6中的锁:MIT6.s081/6.828 lectrue10:Locking 以及 Lab8 locks Part1 心得
这节课程的内容是锁(本节只讨论最基础的锁).其实锁本身就是一个很简单的概念,这里的简单包括 3 点: 概念简单,和实际生活中的锁可以类比,不像学习虚拟内存时,现实世界中几乎没有可以类比的对象,所以即使 ...
- QA|workon env后没有进入虚拟环境,但也没有报错,但cmd可以|Python虚拟环境
问题:pycharm的terminal执行workon env后没有进入虚拟环境,但也没有报错 但cmd可以 原因:因为pycharm的terminal用的是powershell,更改为cmd,重新打 ...
- VMware上安装Centos7
一.下载Centos镜像 国内镜像网站: 清华大学:清华大学开源软件镜像站 | Tsinghua Open Source Mirror 阿里云:阿里巴巴开源镜像站-OPSX镜像站-阿里云开发者社区 ( ...
- sqlite/mysql 省市县三级联动
这个是sqlite的, 改下表结构, 就可以给mysql用了 CREATE TABLE ProvinceCityZone ( _id INTEGER PRIMARY KEY AUTOINCREMENT ...