tree扁平化数据转换为树状结构,树状结构数据扁平化

        大家好,在日常工作中,我们经常会在项目中用到树状数据结构,但是有时候那,跟后端同事对接过程中,返回给前端的数据并不是处理好的树状数据,所以就需要我们自己独立去处理它。下面我封装两个简单的方法,来处理普通数据和树状数据的转换。

1.扁平化数据转换为树状结构

const flatData = [
  { id: 1, name: 'Node 1', parentId: null },
  { id: 2, name: 'Node 1.1', parentId: 1 },
  { id: 3, name: 'Node 1.2', parentId: 1 },
  { id: 4, name: 'Node 1.2.1', parentId: 3 },
  { id: 5, name: 'Node 2', parentId: null }
];

function toTree(items) {
  const tree = []  //存放最终的树状结构
  const itemMap = {} //存放每个节点数据

  for (const item of items) {
    const { id } = item
    itemMap[id] = { ...item, children: [] } //每个节点增加一个children属性,用来存放子节点
  }

  // 遍历所有节点,将每个节点放到其父节点的children数组中
  for (const item of items) {
    const { id, parentId } = item

    // 如果是根节点,则直接放入结果数组中
    if (parentId === null) {
      tree.push(itemMap[id])
    } else {
      // 如果不是根节点,则将当前节点放入其父节点的children数组中 
      // 子元素的parentId 等于  父节点的id  itemMap[parentId] 父节点  //itemMap[id] 当前节点
      if (itemMap[parentId]) itemMap[parentId].children.push(itemMap[id])
    }
  }

  return tree
}

let tree = toTree(flatData)
console.log(tree);
function convertToTree(data) {
  const map = new Map();
  const tree = [];

  data.forEach(node => {
    map.set(node.id, { ...node, children: [] });
  });

  data.forEach(node => {
    const treeNode = map.get(node.id);
    if (node.parentId === null) {
      tree.push(treeNode);
    } else {
      const parentNode = map.get(node.parentId);
      if (parentNode) {
        parentNode.children.push(treeNode);
      } 
    }
  });

  return tree;
}

const treeData = convertToTree(flatData);
console.log(treeData);

2.将树状数据扁平化操作

const treeData = [
  {
    id: 1,
    name: '1',
    children: [
      {
        id: 2,
        name: '1-1',
        children: []
      },
      {
        id: 3,
        name: '1-2',
        children: [
          {
            id: 4,
            name: '1-2-1',
            children: []
          }
        ]
      }
    ]
  },
  {
    id: 5,
    name: '2',
    children: []
  }
];

2.1 使用递归函数来遍历树状结构,并将每个节点转换为一个扁平化的对象,存储在一个数组中。

function flatTree(tree) {
  const result = [];

  function handleTree(node) {
    result.push({ id: node.id, name: node.name })
    
    if (node.children.length > 0) {
      node.children.forEach(child => {
        handleTree(child)
      })
    }
  }

  tree.forEach(node => {
    handleTree(node);
  });

  return result;

}

let flatData = flatTree(treeData);
console.log(flatData);

2.2使用堆栈(stack)来模拟递归过程,这种方法可以避免使用递归函数的调用栈溢出问题,特别是当树的层级非常深时。

function flatTree(tree) {
  const stack = [...tree]
  const result = [];

  while (stack.length > 0) {
    const node = stack.pop();  Array.pop 删除数组的最后一项,返回值是被删除的元素
    result.push({ id: node.id, name: node.name });
    if (node.children.length > 0) {
      stack.push(...node.children)
    }
  }

  return result;
}

let flatData = flatTree(treeData);
console.log(flatData);

以上就是这篇文件的内容,希望能在工作中帮助到大家,有错误请评论指出,谢谢大家!

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值