大家好,在日常工作中,我们经常会在项目中用到树状数据结构,但是有时候那,跟后端同事对接过程中,返回给前端的数据并不是处理好的树状数据,所以就需要我们自己独立去处理它。下面我封装两个简单的方法,来处理普通数据和树状数据的转换。
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);
以上就是这篇文件的内容,希望能在工作中帮助到大家,有错误请评论指出,谢谢大家!