JavaScript树型数据与一维数组相互转换方式
作者:明天也要努力
这篇文章主要介绍了JavaScript树型数据与一维数组相互转换方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
JS树型数据与一维数组相互转换
1. 父子关系数据(一维数组)转换为树型结构数据
1.1 原始数据
var source = [ { id: 1, pid: 0, name: '江苏省' },{ id: 2, pid: 1, name: '南京市' },{ id: 7, pid: 0, name: '上海市' }, { id: 3, pid: 2, name: '鼓楼区' },{ id: 6, pid: 5, name: '武汉市' },{ id: 4, pid: 2, name: '玄武区' },{ id: 5, pid: 0, name: '湖北省' }]
1.2 js代码
function toTree(data) { let result = []; if (!Array.isArray(data)) { return result; } data.forEach(item => { delete item.children; }); let map = {}; data.forEach(item => { map[item.id] = item; // id为键,原数据每一项为值的map对象 }); data.forEach(item => { let parent = map[item.pid]; // item的pid若与map对象的键相同,则item为父级节点 let label = ""; item.label = item.name; if (parent) { (parent.children || (parent.children = [])).push(item); parent.children.forEach(_item => { _item.label = _item.name; }); } else { result.push(item); } }); console.log(result) return result; } toTree(source);
1.3 转换效果
2. 树型结构数据转换为一维数组
2.1 原始数据
const treeObj = { id: '0', name: '中国', children:[ { id: '1', name:'湖北省', children:[ { id: '1-1', name:'武汉市', children:[ { id: '1-1-1', name:'武昌区', }, ] }, ] }, { id: '2', name:'江苏省', children:[ { id: '2-1', name:'南京市', children:[ { id: '2-1-1', name:'玄武区', } ] }, { id: '2-2', name:'镇江市', children:[ { id: '2-2-1', name:'句容市', children: [ { id: '2-2-1-1', name:'下蜀镇', }, ] }, { id: '2-2-2', name:'京口区' }, ] }, ] }, { id: '3', name:'浙江省', } ] };
2.2 js代码
// 将treeObj中的所有对象,放入一个数组中,要求某个对象在另一个对象的children时,其parent_id是对应的另一个对象的id // 其原理实际上是数据结构中的广度优先遍历 function tree2Array(treeObj, rootid) { const temp = []; // 设置临时数组,用来存放队列 const out = []; // 设置输出数组,用来存放要输出的一维数组 temp.push(treeObj); // 首先把根元素存放入out中 let pid = rootid; const obj = deepCopy(treeObj); obj.pid = pid; delete obj['children']; out.push(obj) // 对树对象进行广度优先的遍历 while(temp.length > 0) { const first = temp.shift(); const children = first.children; if(children && children.length > 0) { pid = first.id; const len = first.children.length; for(let i=0;i<len;i++) { temp.push(children[i]); const obj = deepCopy(children[i]); obj.pid = pid; delete obj['children']; out.push(obj) } } } return out } console.log(tree2Array(treeObj, 'root')) // 深拷贝 function deepCopy(obj){ // 深度复制数组 if(Object.prototype.toString.call(obj) === "[object Array]"){ const object=[]; for(let i=0;i<obj.length;i++){ object.push(deepCopy(obj[i])) } return object } // 深度复制对象 if(Object.prototype.toString.call(obj) === "[object Object]"){ const object={}; for(let p in obj){ object[p]=obj[p] } return object } }
2.3 转换效果
JS树结构转换为一维数组,tree转list
let treeData = [{ "pid": null, "id": 2 }, { "pid": null, "id": 3, "children": [{ "pid": 3, "id": 4, "children": [{ "pid": 4, "id": 6, "children": [{ "pid": 6, "id": 5 }] }] }] }] function fn(arr) { let data = JSON.parse(JSON.stringify(arr)) let newData = [] const callback = (item) => { (item.children || (item.children = [])).map(v => { callback(v) }) delete item.children newData.push(item) } data.map(v => callback(v)) return newData } console.log(toTree(fn(treeData)), '===')
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。