数据扁平化和反扁平化

原数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
let flatList = [],
treeList = [
{
"id": 1,
"pid": null,
"label": "第一层",
"value": "1",
"children": [
{
"id": 2,
"pid": 1,
"label": "第二层1",
"value": "2.1",
"children": []
},
{
"id": 3,
"pid": 1,
"label": "第二层2",
"value": "2.2",
"children": []
},
{
"id": 4,
"pid": 1,
"label": "第二层3",
"value": "2.3",
"children": [
{
"id": 5,
"pid": 4,
"label": "第三层1",
"value": "3.1",
"children": []
},
{
"id": 6,
"pid": 4,
"label": "第三层2",
"value": "3.2",
"children": []
}
]
}
]
}
]

数据扁平化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
console.log('tree =>flat,扁平化后:', treeToFlat(JSON.parse(JSON.stringify(treeList)), flatList))

function treeToFlat (treeList, flatList) {
// flatList.length > 9999 是考虑底线保护原则,出于极限保护的目的设置的,可不设或按需设置。
if (flatList.length > 9999) {
return
}
treeList.map(e => {
flatList.push(e)
// 递归:有条件的自己调用自己,条件是 e.children.length 为真
if (e.children && e.children.length) {
treeToFlat(e.children, flatList)
}
})
return flatList
}

数据反扁平化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
console.log('flat =>tree,反扁平化后:', flatToTree(JSON.parse(JSON.stringify(flatList)), treeList))

function flatToTree (flatList, treeList) {
flatList.map(e => {
// 以 e.pid===null,作为判断是不是根节点的依据,或者直接写死根节点(如果确定的话),
// 具体以什么作为判断根节点的依据,得看数据的设计规则,通常是判断层级或是否代表根节点的标记
if (e.pid === null) {
// 避免出现重复数据
const index = treeList.findIndex(sub => sub.id === e.id)
if (index === -1) {
treeList.push(e)
}
}
flatList.map(e2 => {
if (e2.pid === e.id) {
// 避免出现重复数据
const index = e.children.findIndex(sub => sub.id === e2.id)
if (index === -1) {
e.children.push(e2)
}
}
})
})
return treeList
}

数据扁平化(reduce)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
function treeToFlat(data, key = 'ParentId', children = 'Children') {
<!-- 此处需要使用function,不能使用箭头函数,否则下方的arguments存在异常 -->
const result = data.reduce(function (prev, curr) {
let obj = {};
for (var c in curr) {
if (c !== children) Object.assign(obj, { [c]: curr[c] });
}
prev.push(obj);
curr[children] &&
curr[children].forEach((v) => {
v[key] = curr["id"] || curr["Id"];
arguments.callee(prev, v);
});
return prev;
}, []);
return result;
}

数据反扁平化(reduce)

1
2
3
4
5
6
7
8
9
10
11
function flatToTree(data, key = 'ParentId', children = 'Children'){
const result = data.reduce(function(prev, curr, i, arr){
curr[children] = arr.filter(v => v[key] === (curr["Id"] || curr["id"]));
if(!curr[key]){
prev.push(curr)
}
return prev;
}, [] )
return result
}