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 ...
随机推荐
- flink-cdc同步mysql数据到elasticsearch
1,什么是cdc CDC是(Change Data Capture 变更数据获取)的简称.核心思想是,监测并捕获数据库的变动(包括数据 或 数据表的插入INSERT.更新UPDATE.删除DELETE ...
- 一文详解自然语言处理两大任务与代码实战:NLU与NLG
自然语言处理(NLP)涵盖了从基础理论到实际应用的广泛领域,本文深入探讨了NLP的关键概念,包括词向量.文本预处理.自然语言理解与生成.统计与规则驱动方法等,为读者提供了全面而深入的视角. 作者 Te ...
- CF-1860C Game on Permutation题解
题意:在一条数轴上,Alice可以跳到在你所在点前面且值比当前所在点小的点.每回合可以向任意符合要求的点跳一次.当轮到Alice的回合同时不存在符合要求的点,Alice就赢了.Alice可以选择一个点 ...
- CTC蜀道会:第一次圆桌会圆满结束
近期,成都.NET俱乐部核心成员经过讨论会,我们成立了CTC蜀道会,它是一个专注于创业历程.研发管理.AIGC.副业之路..NET.Vue.微软技术.开源技术等领域的社区,立足于蓉城成都,致力于连接同 ...
- [Lua] 实现所有类的基类Object、模拟单继承OO、实现抽象工厂
所有类的基类 Object Lua 没有严格的 oo(Object-Oriented)定义,可以利用元表特性来实现 先定义所有类的基类,即Object类.代码顺序从上到下,自成一体.完整代码 定义一个 ...
- mybatis数据库字段自动填充
背景描述 目前,大多数项目的数据库设计,都会添加一些公共字段,比如version(版本号).deleted(逻辑删除标识).create_time.update_time.create_by.upda ...
- Elasticsearch之索引简单应用
本篇所有操作都在 Kibana 上执行 创建第一个索引 PUT product { // 索引设置 "settings": { // 分片数量 "number_of_sh ...
- 推荐一个react上拉加载更多插件:react-infinite-scroller
在开发网页和移动应用时,经常需要处理大量数据的展示和加载.如果数据量非常大,一次性全部加载可能会导致页面卡顿或崩溃.为了解决这个问题,我们可以使用无限滚动(Infinite Scroll)的技术.Re ...
- 简单聊一聊SpringBoot的约定优于配置
Spring Boot的约定优于配置 对于今天聊的SpringBoot的约定优于配置,我打算从三个方面去展开: 1.什么是约定优于配置 1> 约定优于配置是一种软件设计的范式,其核心思想:使用一 ...
- 「shoi 2012」随机数
link. 对于 pass 1, 你把他考虑成 \(\frac{\sum x}{i}\) 的形式, 于是每次操作的贡献就是 \(\frac{2}{i}\), 那么答案就是 \(\sum_{i=2}^n ...