JavaScript树型数据与一维数组相互转换方式

 更新时间:2023年06月07日 11:09:21   作者:明天也要努力  
这篇文章主要介绍了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)), '===')

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • JS搜狐面试题分析

    JS搜狐面试题分析

    这篇文章主要介绍了JS搜狐面试题,涉及javascript数组、字符串及面向对象程序设计相关技巧,需要的朋友可以参考下
    2016-12-12
  • 前端高频面试题之JS中堆和栈的区别和浏览器的垃圾回收机制

    前端高频面试题之JS中堆和栈的区别和浏览器的垃圾回收机制

    本文给大家分享前端高频面试题JS中堆和栈的区别和浏览器的垃圾回收机制,本文分文别类给大家介绍了栈(stack)和堆(heap)的区别基本类型和引用类型的相关知识,浏览器垃圾回收机制包括基本概念给大家介绍的非常详细,需要的朋友参考下吧
    2023-10-10
  • 一个很酷的拖动层的js类,兼容IE及Firefox

    一个很酷的拖动层的js类,兼容IE及Firefox

    自己优化修改了网上的一个JS拖动类,增加了拖动时显示半透明的特效。
    2009-06-06
  • JavaScript中SetInterval与setTimeout的用法详解

    JavaScript中SetInterval与setTimeout的用法详解

    在写H5游戏时经常需要使用定时刷新页面实现动画效果,比较常用即setTimeout()以及setInterval(),但是大家对SetInterval与setTimeout的用法了解吗,下面通过本文给大家详解js中SetInterval与setTimeout的用法,需要的朋友参考下
    2015-11-11
  • javascript 24点游戏代码

    javascript 24点游戏代码

    非常不错的技术24点的游戏代码,他的算法值得学习,希望喜欢游戏的朋友,可以来看看
    2008-06-06
  • 通过js简单实现将一个文本内容转译成加密文本

    通过js简单实现将一个文本内容转译成加密文本

    将文本内容转译成加密文本,在某些情况下还是比较实用的,下面通过js简单实现下,感兴趣的朋友不要错过
    2013-10-10
  • vue3 uniapp微信登录功能实现

    vue3 uniapp微信登录功能实现

    根据最新的微信小程序官方的规定,uniapp中的uni.getUserInfo方法不再返回用户头像和昵称、以及手机号,这篇文章主要介绍了vue3 uniapp微信登录功能实现,需要的朋友可以参考下
    2024-04-04
  • js实现鼠标悬浮给图片加边框的方法

    js实现鼠标悬浮给图片加边框的方法

    这篇文章主要介绍了js实现鼠标悬浮给图片加边框的方法,涉及jquery.insetborder.js中borderEffect方法的使用技巧,具有一定参考借鉴价值,需要的朋友可以参考下
    2015-01-01
  • Javascript iframe交互并兼容各种浏览器的解决方法

    Javascript iframe交互并兼容各种浏览器的解决方法

    这篇文章主要介绍了Javascript iframe交互并兼容各种浏览器的解决方法的相关资料,非常不错,具有参考借鉴价值,需要的朋友可以参考下
    2016-07-07
  • JavaScript字符串转数字的多种方法总结

    JavaScript字符串转数字的多种方法总结

    在 JavaScript 开发中,我们经常需要将字符串转换为数字,例如从输入框获取用户输入后进行数学计算,JavaScript 提供了多种方法来实现这一功能,如 parseInt、parseFloat、Number 等,本文将详细介绍这些方法的使用方式、适用场景以及可能的坑,需要的朋友可以参考下
    2025-03-03

最新评论