Skip to content

Commit 72bfb57

Browse files
authored
refactor: refactored flattenData and findAllParents methods and added tests (#418)
1 parent 09de858 commit 72bfb57

File tree

5 files changed

+149
-45
lines changed

5 files changed

+149
-45
lines changed

src/@types/common.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,9 @@ export type TableSizeChangeEventName =
2020
| 'widthChanged'
2121
| 'heightChanged';
2222

23-
export interface RowDataType {
23+
export interface RowDataType<T = never> {
2424
dataKey?: string;
25-
children?: RowDataType[];
25+
children?: T[];
2626
[key: string]: any;
2727
}
2828

src/utils/findAllParents.ts

Lines changed: 11 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,20 @@
11
import { PARENT_KEY } from '../constants';
2-
import type { RowKeyType, RowDataType } from '../@types/common';
2+
import type { RowDataType, RowKeyType } from '../@types/common';
33

44
/**
5-
* Find all parent nodes of a node
5+
* Get all parent nodes of the given node in the flattened data
6+
* @param node target node
67
*/
7-
export default function findAllParents<Row extends RowDataType, Key>(
8-
rowData: Row,
9-
rowKey: RowKeyType
10-
): Key[] {
8+
function findAllParents<Row extends RowDataType, Key>(node: Row, rowKey: RowKeyType): Key[] {
119
const parents: Key[] = [];
10+
let current = node[PARENT_KEY];
1211

13-
if (!rowData) {
14-
return parents;
12+
// Iterate up through the parent chain and add each parent to the result array
13+
while (current) {
14+
parents.push(current[rowKey]);
15+
current = current[PARENT_KEY];
1516
}
16-
17-
function findParent(data) {
18-
if (data) {
19-
parents.push(data[rowKey]);
20-
21-
if (data[PARENT_KEY]) {
22-
findParent(data[PARENT_KEY]);
23-
}
24-
}
25-
}
26-
findParent(rowData[PARENT_KEY]);
27-
2817
return parents;
2918
}
19+
20+
export default findAllParents;

src/utils/flattenData.ts

Lines changed: 13 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -2,31 +2,21 @@ import { PARENT_KEY } from '../constants';
22
import type { RowDataType } from '../@types/common';
33

44
/**
5-
* Flatten the data of a tree structure into a one-dimensional array.
6-
* @param treeData
7-
* @returns
5+
* Flatten the tree data with parent association recorded on each node
6+
* @param tree tree data
87
*/
9-
function flattenData<Row extends RowDataType>(treeData: readonly Row[]) {
10-
const flattenItems: Row[] = [];
8+
function flattenData<Row extends RowDataType<Row>>(tree: readonly Row[], parent?: Row): Row[] {
9+
return tree.reduce<Row[]>((acc, node) => {
10+
// Create a new flattened node with parent association
11+
const flattened = {
12+
...node,
13+
[PARENT_KEY]: parent
14+
};
1115

12-
function loop(treeData, parentNode) {
13-
if (!Array.isArray(treeData)) {
14-
return;
15-
}
16-
17-
treeData.forEach(rowData => {
18-
rowData[PARENT_KEY] = parentNode;
19-
flattenItems.push({
20-
...rowData
21-
});
22-
if (rowData.children) {
23-
loop(rowData.children, rowData);
24-
}
25-
});
26-
}
27-
28-
loop(treeData, null);
29-
return flattenItems;
16+
// Add the flattened node and its flattened children (if any) to the result array
17+
acc.push(flattened, ...(node.children ? flattenData(node.children, flattened) : []));
18+
return acc;
19+
}, []);
3020
}
3121

3222
export default flattenData;

test/findAllParentsSpec.js

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import findAllParents from '../src/utils/findAllParents';
2+
import { PARENT_KEY } from '../src/constants';
3+
4+
describe('findAllParents', () => {
5+
it('should find all parents of a node', () => {
6+
const tree = {
7+
id: 1,
8+
name: 'A',
9+
[PARENT_KEY]: {
10+
id: 2,
11+
name: 'B',
12+
[PARENT_KEY]: {
13+
id: 3,
14+
name: 'C',
15+
[PARENT_KEY]: undefined
16+
}
17+
}
18+
};
19+
20+
const result = findAllParents(tree, 'id');
21+
22+
expect(result).to.deep.equal([2, 3]);
23+
});
24+
25+
it('should return an empty array if the node has no parents', () => {
26+
const node = { id: 1, name: 'A', [PARENT_KEY]: undefined };
27+
28+
const result = findAllParents(node, 'id');
29+
30+
expect(result).to.deep.equal([]);
31+
});
32+
});

test/flattenDataSpec.js

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
import flattenData from '../src/utils/flattenData';
2+
import { PARENT_KEY } from '../src/constants';
3+
4+
describe('flattenData', () => {
5+
it('should flatten a single-level tree', () => {
6+
const tree = [
7+
{ id: '1', name: 'A' },
8+
{ id: '2', name: 'B' },
9+
{ id: '3', name: 'C' }
10+
];
11+
12+
const result = flattenData(tree);
13+
14+
expect(result).to.deep.equal(tree.map(node => ({ ...node, [PARENT_KEY]: undefined })));
15+
});
16+
17+
it('should flatten a multi-level tree', () => {
18+
const tree = [
19+
{
20+
id: '1',
21+
name: 'A',
22+
children: [
23+
{ id: '2', name: 'B' },
24+
{
25+
id: '3',
26+
name: 'C',
27+
children: [
28+
{ id: '4', name: 'D' },
29+
{ id: '5', name: 'E' }
30+
]
31+
},
32+
{ id: '6', name: 'F' }
33+
]
34+
},
35+
{
36+
id: '7',
37+
name: 'G',
38+
children: [
39+
{ id: '8', name: 'H' },
40+
{ id: '9', name: 'I' }
41+
]
42+
},
43+
{ id: '10', name: 'J' }
44+
];
45+
46+
const result = flattenData(tree);
47+
48+
expect(result).to.have.lengthOf(10);
49+
expect(result).to.deep.equal([
50+
{
51+
id: '1',
52+
name: 'A',
53+
children: [
54+
{ id: '2', name: 'B' },
55+
{
56+
id: '3',
57+
name: 'C',
58+
children: [
59+
{ id: '4', name: 'D' },
60+
{ id: '5', name: 'E' }
61+
]
62+
},
63+
{ id: '6', name: 'F' }
64+
]
65+
},
66+
{ id: '2', name: 'B' },
67+
{
68+
id: '3',
69+
name: 'C',
70+
children: [
71+
{ id: '4', name: 'D' },
72+
{ id: '5', name: 'E' }
73+
]
74+
},
75+
{ id: '4', name: 'D' },
76+
{ id: '5', name: 'E' },
77+
{ id: '6', name: 'F' },
78+
{
79+
id: '7',
80+
name: 'G',
81+
children: [
82+
{ id: '8', name: 'H' },
83+
{ id: '9', name: 'I' }
84+
]
85+
},
86+
{ id: '8', name: 'H' },
87+
{ id: '9', name: 'I' },
88+
{ id: '10', name: 'J' }
89+
]);
90+
});
91+
});

0 commit comments

Comments
 (0)