js将对象数组中具有父子关系的数据换成树形结构

本文介绍了一种使用JavaScript将具有父子关系的数据转换为树形结构的方法。通过递归算法实现,适用于角色权限管理等场景。文章提供了完整的代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

let allRes = [
  {
    id: 4,
    resName: "删除角色",
    parentId: 2
  },
  {
    id: 3,
    resName: "编辑角色",
    parentId: ''
  },
  {
    id: 2,
    resName: "设置权限",
    parentId: ''
  },
  {
    id: 5,
    resName: "添加用户",
    parentId: 4
  },
  {
    id: 6,
    resName: "更新用户",
    parentId: 4
  },
  {
    id: 7,
    resName: "删除用户",
    parentId: 6
  },
  {
    id: 8,
    resName: "重置密码",
    parentId: 3
  },
  {
    id: 9,
    resName: "添加地区",
    parentId: 5
  },
  {
    id: 10,
    resName: "编辑地区",
    parentId: 6
  }
];

function treeObj(originObj){
	//对象深拷贝
	let obj ={};
	for (key in originObj){
		var val = originObj[key];
  		obj[key] = typeof val === 'object' ? arguments.callee(val):val;
   }
   //对象新增children键值,用于存放子树
   obj['children'] = [];
   return obj;
}

//data:带转换成树形结构的对象数组
//attributes:对象属性
function toTreeData (data, attributes) {
  let resData = data;
  let tree = [];

 //找寻根节点
  for (let i = 0; i < resData.length; i++) {

    if (resData[i][attributes.parentId] === ''|| resData[i][attributes.parentId] === null) {
      tree.push( treeObj(resData[i]) );
      resData.splice(i, 1);
      i--;
    }
  }

  run(tree);

  //找寻子树
  function run(chiArr) {
    if (resData.length !== 0) {
      for (let i = 0; i < chiArr.length; i++) {
        for (let j = 0; j < resData.length; j++) {
          if (chiArr[i][attributes.id] === resData[j][attributes.parentId]){
            let obj = treeObj(resData[j]);
            chiArr[i].children.push(obj);
            resData.splice(j, 1);
            j--;
          }
        }
        run(chiArr[i].children);
      }
    }
  }

  return tree;

}

let data = allRes;
// 属性配置信息
let attributes = {
      id: 'id',
      parentId: 'parentId',
  };
let treeData = toTreeData(data, attributes);

console.log(treeData);
</script>
本文根据 《js将有父子关系的数据转换成树形结构数据》博客进行适当改编。
### Vue 实现数组树形结构 在 Vue 项目中,可以创建一个方法来将扁平化的数组换成树形结构数据。此过程涉及遍历原始数组并构建父子关系。 对于给定的节点列表,假设每个对象都有 `id` 和 `parentId` 属性用于表示唯一标识符及其关联[^1]: ```javascript function arrayToTree(data, rootId = null) { const treeData = []; // 创建映射表提高查找效率 const idMap = new Map(); data.forEach(item => { item.children = []; idMap.set(item.id, item); }); data.forEach(item => { if (item.parentId === rootId || !rootId && !item.parentId) { treeData.push(item); } else { let parentItem = idMap.get(item.parentId); if (parentItem) { parentItem.children.push(item); } } }); return treeData; } ``` 为了使该函数适用于 Vue 组件内部,在 methods 或 computed 中定义上述逻辑,并确保传入的数据已经过适当处理以便于展示[^2]。 当需要渲染这些嵌套结构时,可以通过递归组件的方式轻松完成视图层面上的表现。下面是一个简单的例子说明如何利用这个工具函数以及相应的模板代码片段[^3]: ```vue <template> <ul> <li v-for="node in nodes" :key="node.id"> {{ node.name }} <tree-view v-if="node.children.length" :nodes="node.children"></tree-view> </li> </ul> </template> <script> export default { name: 'TreeView', props: ['nodes'], }; </script> ``` 通过这种方式可以在前端高效地呈现具有层次感的信息架构,同时也保持了良好的可维护性和扩展性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值