JavaScript 数组结构与树结构相互转换

2,563 阅读2分钟

作为前端开发的同学,在与后端进行数据联调的时候,处理Array数组结构的数据是最多的。当数组中涉及层级嵌套时,我们的数组结构就需要转化为Tree树结构。常见的有目录树组件,区域选择组件等。

这种树结构数据,一般都是后端进行处理的,再将处理完的结果返回给前端。但是当后端直接返回一个数组让前端处理的时候,我们需要懂得如何去处理。本文将带大家学习数组结构与树结构相互转换!

数组结构与树结构相互转换的方法其实有多种,这里只给出一种方法供大家学习研究!

1. Array -> Tree

我们要把下面这种数组结构转化为像tree那样嵌套的结构(根据父子关系):

/** 数组结构数据 */
const arrayData = [
  { id: 2, title: '中国', parent_id: 0 },
  { id: 3, title: '广东省', parent_id: 2 },
  { id: 4, title: '广州市', parent_id: 3 },
  { id: 5, title: '天河区', parent_id: 4 },
  { id: 6, title: '湖南省', parent_id: 2 },
  { id: 1, title: '俄罗斯', parent_id: 0 }
]

递归查找添加children:

/**
 * 递归查找添加children
 * @param {数组数据} data 
 * @param {存放返回结果} result 
 * @param {父id} pid 
 */
function getChildren(data, result, pid) {
  for (const item of data) {
    if (item.parent_id === pid) {
      const newItem = { children: [], ...item }
      result.push(newItem)
      getChildren(data, newItem.children, item.id)
    }
  }
}

转化方法:

/**
 * 转化方法
 * @param {数组数据} data 
 * @param {父id} pid 
 * @returns 
 */
function arrayToTree(data, pid) {
  let result = []
  getChildren(data, result, pid)
  return result
}

console.log(arrayToTree(arrayData, 0));

结果如下:

image.png

2. Tree -> Array

我们要把下面这种tree树结构的转化为扁平化的一维数组:

/** 树状形结构数据treeData */
const treeData = [
  {
    id: 2, title: '中国', parent_id: 0,
    children: [
      {
        id: 3, title: '广东省', parent_id: 2,
        children: [
          {
            id: 4, title: '广州市', parent_id: 3,
            children: [
              { id: 5, title: '天河区', parent_id: 4 }
            ]
          }
        ]
      },
      { id: 6, title: '湖南省', parent_id: 2 }
    ]
  },
  { id: 1, title: '俄罗斯', parent_id: 0, },
]

转化方法:

function treeToList(data) {
        let res = [];
        const dfs = (tree) => {
            tree.forEach((item) => {
                if (item.children) {
                    dfs(item.children);
                    delete item.children;
                }
                res.push(item);
            });
        };
        dfs(data);
        return res;
}

结果如下:

image.png

3. Tree 查找路径(id)

使用目录的时候会有这样的需求,根据id查找所在目录路径,也是递归实现。

/**
 * 根据id查找所在目录路径
 * @param {树结构的数组数据} tree 
 * @param {要查找的id} id 
 * @param {初始路径} path 
 * @returns 
 */
function parseTreePath(tree, id, path = "") {
  for (let i = 0; i < tree.length; i++) {
    let tempPath = path;
    // 避免出现在最前面的/
    tempPath = `${tempPath ? tempPath + "/ " : tempPath}${tree[i].title}`; 
    if (tree[i].id == id) return tempPath;
    else if (tree[i].children) {
      let reuslt = parseTreePath(tree[i].children, id, tempPath);
      if (reuslt) return reuslt;
    }
  }
};
console.log(parseTreePath(treeData, 5));

结果如下:

image.png