今天又遇到了需要将行数据转换成树形结构数据的需求,本来是打算用递归的。但是想了想,递归这种东西,如果层级多了,可能会导致内存溢出,也影响效率。于是有了下面这个方式,感觉算是时间复杂度最低的了吧?就经历了一次循环。(如有不足,可指出一起讨论讨论)
// 存在上下级关系的行数据
const list = [
{ id: "01", pid: "0", name: "01" },
{ id: "02", pid: "0", name: "02" },
{ id: "01-01", pid: "01", name: "01-01" },
{ id: "01-02", pid: "01", name: "01-02" },
{ id: "01-02-01", pid: "01-02", name: "01-02-01" },
{ id: "01-02-02", pid: "01-02", name: "01-02-02" },
{ id: "01-02-03", pid: "01-02", name: "01-02-03" },
{ id: "01-02-03-01", pid: "01-02-03", name: "01-02-03-01" },
{ id: "01-02-03-02", pid: "01-02-03", name: "01-02-03-02" }
];
// 行结构数据转化为树形结构数据
function rowData2TreeData(rows, config) {
const keyNodes = {}, parentKeyNodes = {};
for (let i = 0; i < rows.length; i++) {
let row = rows[i]; // 将行数据整体赋值后再做需要的处理
row.id = row[config.id];
row[config.pid] = row[config.pid];
row[config.children] = [];
keyNodes[row.id] = row;
if (parentKeyNodes[row[config.pid]]) { parentKeyNodes[row[config.pid]].push(row); }
else { parentKeyNodes[row[config.pid]] = [row]; }
let children = parentKeyNodes[row.id];
if (children) { row[config.children] = children; }
let pNode = keyNodes[row[config.pid]];
if (pNode) { pNode[config.children].push(row); }
}
return parentKeyNodes[config.rootKey];
}
// 属性配置信息
const config = {
id: 'id',// id字段
pid: 'pid',// 上级id字段
children: 'subNode',// 生成的下级节点key字段
rootKey: '0' // 根节点上级id
}
let data = rowData2TreeData(list, config)
console.log(data)
可根据需要对config进行配置,产出自己想要的数据字段。以上代码可以直接复制粘贴运行。结果如下