前言
在最近项目中,需要按省市来筛选数据,我们得生成对应的树形结构数据。这里记录下数据转换的一些方法。
树形结构数据生成
在实际项目中,信息一般在后台保存为以下格式:
const datas = [
{ id: 1, parentId: 0 },
{ id: 2, parentId: 1 },
{ id: 3, parentId: 1 },
...
];
而前端需要转换为以下格式:
const trees = [
{
id: 0,
childrens: [
{
id: 1,
childrens: [],
},
{
id: 2,
childrens: [
{
id: 3,
childrens: [],
}
],
}
],
},
...
];
思路
为了进行数据转换,我们执行以下的步骤:
- 声明一个空对象
treeKeyObj
,用于记录每个id下的子节点。 - 遍历
datas
,根据其parentId
信息,更新treeKeyObj
中父节点id和对应的子节点数据。 - 遍历
datas
,根据treeKeyObj
给每个节点添加childrens
,并生成新的数组list
。 - 根据根节点的逻辑,过滤出
list
中的根节点。
注:由于JavaScript中对象是按引用传递,而这里的节点就是一个对象。所以在第3步中,给节点添加childrens
后,其childrens
中对应节点也会有相应的childrens
。
实现
function list2Tree(listParams, filterRootFn) {
const list = JSON.parse(JSON.stringify(listParams));
const treeKeyObj = {};
if (list.length > 0) {
list.forEach(item => {
const key = item.parentId;
(treeKeyObj[key] || (treeKeyObj[key] = [])).push(item);
});
list.forEach(item => {
const treeKey = item.id;
item.childrens = treeKeyObj[treeKey] || [];
});
}
return list.filter(filterFn);
}
优化
- 这里格式里面的
id
、parentId
和childrens
,可以作为参数传入来实现动态生成 filterRootFn
也可以传入一个字符串,用于标识根节点的id
值来进行过滤处理
其他(未完待续)
除此之外,还有针对当前节点的所有子节点的查询、所有叶子节点的查询等,就放在后面进行更新。。。