规则
规则
subject_no以小数点为段,每一段数字进行匹配,如:x包含x.y,x.z
未能精确匹配的, x包含x.y.z,x.n.m
未能精确匹配的, x.y包含x.y.z,x.a.b.c.d
初始数据
var no_list = [
{
subject_no: '10.3',
},
{
subject_no: '10',
},
{
subject_no: '10.3.1',
},
{
subject_no: '10.4.3.1',
},
{
subject_no: '10.3.2',
},
{
subject_no: '10.4.3',
},
{
subject_no: '10.3.2.1.1',
},
{
subject_no: '10.4.3.2.1',
},
{
subject_no: '10.4.3.2.1.2',
},
{
subject_no: '10.4.3.2.1.0',
},
{
subject_no: '10.4.3.2.1.0.5.6',
}
]
需要处理成的结果数据
var result_tree = [
{
subject_no: '10',
children: [
{
subject_no: '10.3',
children: [
{
subject_no: '10.3.1',
},
{
subject_no: '10.3.2',
children: [
{
subject_no: '10.3.2.1.1',
},
]
},
]
},
{
subject_no: '10.4.3',
children: [
{
subject_no: '10.4.3.1',
children: [
{
subject_no: '10.4.3.2.1',
children: [
{
subject_no: '10.4.3.2.1.0',
children: [
{
subject_no: '10.4.3.2.1.0.5.6',
}
]
},
{
subject_no: '10.4.3.2.1.2',
},
]
},
]
},
]
},
]
},
]
算法实现
function list2tree(list) {
// 初始化匹配map
let map = list.reduce((m, i) => {
m[i.subject_no] = i
return m
}, {
})
let tree = []
for (let i = 0; i < list.length; i++) {
let pathArr = list[i].subject_no.split('.')
//-1的目的是为了避免后面匹配到自己,否则会陷入死循环
let j = pathArr.length - 1;
// 遍历路径数组
for (; j > 0; j--) {
// 从后往前取,直到map中有数据
let path = pathArr.slice(0, j).join('.')
// 有数据就放入children
if (map[path]) {
if (!map[path].children) {
map[path].children = []
}
map[path].children.push(list[i])
break
}
}
j === 0 && tree.push(list[i])
}
return tree
}
console.log(list2tree(no_list))