let data = [
{
"id": 1,
"project": "项目1",
"operation": "运营商1",
"version": "版本1",
"name": "名称1",
"age": "23",
"address": "地址1"
},
{
"id": 2,
"project": "项目2",
"operation": "运营商1",
"version": "版本1",
"name": "名称1",
"age": "23",
"address": "地址1"
},
{
"id": 3,
"project": "项目1",
"operation": "运营商2",
"version": "版本1",
"name": "名称1",
"age": "23",
"address": "地址1"
},
{
"id": 4,
"project": "项目2",
"operation": "运营商1",
"version": "版本1",
"name": "名称1",
"age": "23",
"address": "地址1"
},
{
"id": 5,
"project": "项目1",
"operation": "运营商2",
"version": "版本2",
"name": "名称1",
"age": "23",
"address": "地址1"
}
]
const indexArray = ["project", "version", "operation"];
/**
* 第一个函数的思路是逐个遍历原始数据数组中的每个项,并根据索引层级数组构建树状结构。它通过嵌套的循环来逐层创建节点,并将数据项插入到正确的节点中。
具体思路如下:
初始化根节点数组 root,用于存储最终的树状结构。
对于数据数组中的每个项 item,从根节点数组开始构建层级。
针对每个索引层级,依次进行处理:
获取当前索引对应的值 value,即 item[index]。
在当前层级 currentLevel 中查找具有相同标签 value 的子节点 child。
如果找不到子节点,创建一个新的子节点 child,并将其加入到当前层级 currentLevel 中。
将 currentLevel 更新为新的子节点的子节点数组,即 currentLevel = child.children。
在最后一层节点的子节点数组中,将当前项 item 直接插入。
循环结束后,返回根节点数组 root,即构建好的树状结构。
这个函数的主要思路是通过循环和条件判断逐层构建树的结构,但它没有使用更高级的数据结构或算法来优化查找操作的效率,因此时间复杂度较高。
*/
function buildTree1(data, indexArray) {
const root = [];
for (const item of data) {
let currentLevel = root;
for (const index of indexArray) {
const value = item[index];
let child = currentLevel.find(node => node.label === value);
if (!child) {
child = { label: value, children: [] };
currentLevel.push(child);
}
currentLevel = child.children;
}
currentLevel.push(item);
}
return root;
}
/**
* 具体思路如下:
初始化根节点数组 root,用于存储最终的树状结构。
初始化空的哈希表 nodeMap,用于存储已经构建的节点。
对于数据数组中的每个项 item,从根节点数组开始构建层级。
针对每个索引层级,依次进行处理:
获取当前索引对应的值 value,即 item[index]。
根据索引和值生成唯一的节点标识 nodeId,例如使用 index + '_' + value。
在哈希表 nodeMap 中查找具有标识 nodeId 的节点 child。
如果找不到节点,说明该节点尚未构建,创建一个新的子节点 child,并将其加入到当前层级 currentLevel 和哈希表 nodeMap 中。
将 currentLevel 更新为新的子节点的子节点数组,即 currentLevel = child.children。
在最后一层节点的子节点数组中,将当前项 item 直接插入。
循环结束后,返回根节点数组 root,即构建好的树状结构。
这个函数的主要思路是利用哈希表存储已经构建的节点,通过哈希表的快速查找能力,减少了查找操作的时间复杂度。这样可以在构建树的过程中快速定位已经存在的节点,避免重复创建,从而提高了整体的效率。
*/
function buildTree2(data, indexArray) {
const root = [];
const nodeMap = {}; // 哈希表用于存储已构建的节点
for (const item of data) {
let currentLevel = root;
for (const index of indexArray) {
const value = item[index];
const nodeId = index + '_' + value;
let child = nodeMap[nodeId];
if (!child) {
child = { label: value, children: [] };
nodeMap[nodeId] = child;
currentLevel.push(child);
}
currentLevel = child.children;
}
currentLevel.push(item);
}
return root;
}
const tree = buildTree(data, indexArray);
console.log(tree);
[
{
"label": "项目1",
"children": [
{
"label": "版本1",
"children": [
{
"label": "运营商1",
"children": [
{
"id": 1,
"project": "项目1",
"operation": "运营商1",
"version": "版本1",
"name": "名称1",
"age": "23",
"address": "地址1"
}
]
},
{
"label": "运营商2",
"children": [
{
"id": 3,
"project": "项目1",
"operation": "运营商2",
"version": "版本1",
"name": "名称1",
"age": "23",
"address": "地址1"
}
]
}
]
},
{
"label": "版本2",
"children": [
{
"label": "运营商2",
"children": [
{
"id": 5,
"project": "项目1",
"operation": "运营商2",
"version": "版本2",
"name": "名称1",
"age": "23",
"address": "地址1"
}
]
}
]
}
]
},
{
"label": "项目2",
"children": [
{
"label": "版本1",
"children": [
{
"label": "运营商1",
"children": [
{
"id": 2,
"project": "项目2",
"operation": "运营商1",
"version": "版本1",
"name": "名称1",
"age": "23",
"address": "地址1"
},
{
"id": 4,
"project": "项目2",
"operation": "运营商1",
"version": "版本1",
"name": "名称1",
"age": "23",
"address": "地址1"
}
]
}
]
}
]
}
]