JS 扁平数组转树形数组
/**
* nodes:扁平数组
* options:配置项;
* sortFiled未传值时不进行排序,如果传入排序属性,默认升序排列
*/
function buildTree(nodes, options) {
const {
idKey = 'id',
pidKey = 'pid',
childrenKey = 'children',
sortField,
sortAsc = true
} = options;
const nodeMap = new Map();
const rootNodes = [];
// 将所有节点放入一个映射表中以便快速查找
nodes.forEach(node => {
node[childrenKey] = [];
nodeMap.set(node[idKey], node);
});
// 遍历每个节点,将其添加到父节点的children列表中
nodes.forEach(node => {
const parent = nodeMap.get(node[pidKey]);
if (!parent) { // 如果没有找到父节点,则是根节点
rootNodes.push(node);
} else {
parent[childrenKey].push(node);
}
});
// 如果提供了排序字段,则进行排序
if (sortField !== undefined) {
// 排序子节点
function sortChildren(parentNode) {
if (parentNode[childrenKey] && parentNode[childrenKey].length > 0) {
parentNode[childrenKey].sort((a, b) => {
const comparison = a[sortField] < b[sortField] ? -1 : (a[sortField] > b[sortField] ? 1 : 0);
return sortAsc ? comparison : -comparison;
});
parentNode[childrenKey].forEach(child => {
sortChildren(child); // 递归排序子节点
});
}
}
// 对每个根节点进行排序
rootNodes.sort((a, b) => {
const comparison = a[sortField] < b[sortField] ? -1 : (a[sortField] > b[sortField] ? 1 : 0);
return sortAsc ? comparison : -comparison;
});
rootNodes.forEach(root => sortChildren(root));
}
return rootNodes;
}
树型数组转扁平数组
function flattenTree(tree, childrenKey = 'children') {
let flatArray = [];
function traverse(node) {
// 创建一个只包含 id 和 pid 的新对象
const nodeCopy = {
id: node.id,
pid: node.pid
};
flatArray.push(nodeCopy); // 添加当前节点到扁平数组
if (node[childrenKey] && node[childrenKey].length > 0) {
node[childrenKey].forEach(child => {
traverse(child); // 递归遍历子节点
});
}
}
tree.forEach(root => {
traverse(root); // 从根节点开始遍历
});
return flatArray;
}