/**
* 前两版
* (一)
* (二)
*
* 最终版本!!!!
* 从上到下
* 当前层级大于前项层级,就会作为前项的子
* 当前层级小于前项层级,并且大于某个层级,那就作为这个层级的子
* 当前层级小于前项层级,并且找不到小于其的层级,就会作为第一级
*/
const arr = [
{
"title": 'aaaaa',
"href": '#ffasss',
"level": "1"
},
{
"title": "Getting Started",
"href": "#getting-started",
"level": "2"
},
{
"title": "Documentawqtion",
"href": "#docum2323entation",
"level": "4"
},
{
"title": "Documentwwation",
"href": "#documentwwwation",
"level": "5"
},
{
"title": "Documentatrqion",
"href": "#documentation",
"level": "6"
},
{
"title": "Installation",
"href": "#installation",
"level": "3"
},
{
"title": "API",
"href": "#api",
"level": "4"
},
{
"title": "I18n",
"href": "#i18n",
"level": "3"
},
{
"title": "Plugin",
"href": "#plugin",
"level": "3"
},
{
"title": "Sponsors",
"href": "#sponsors",
"level": "2"
},
{
"title": "Contributors",
"href": "#contributors",
"level": "2"
},
{
"title": "License",
"href": "#license",
"level": "2"
},
{
"title": "License",
"href": "#contributorsLicense",
"level": "1"
}
]
const newArr = []
// 映射数组
const maps = []
const mark = {
curDeep: 0,
targetDeep: null,
parentObj: null,
}
function recursive(arr, raw, positive = true) {
if (!Array.isArray(arr) || !raw) return
// 解构
const { parentObj, curDeep, targetDeep } = mark
// 存在 targetDeep 说明需要递归查找
if (targetDeep) {
// 如果 curDeep 与 targetDeep 不等,则继续递归
if (curDeep !== targetDeep) {
// 当前层末尾项作为 parentObj, 递归其 children
const lastObj = arr[arr.length - 1]
mark.parentObj = lastObj
// 递归进入下一层
mark.curDeep++
return recursive(lastObj.children, raw)
} else {
// 关闭 targetDeep
mark.targetDeep = null
// 重新递归,执行数据填充
return recursive(arr, raw)
}
} else {
// 处理数据,当前数据,作为 child 子项,并且增加 children 方便后继其子级的填充
const childObj = Object.assign({ children: [] }, raw)
const isFindMap = maps.find(map => map.k === childObj.href)
// 当前映射项
const mapItem = isFindMap || { k: childObj.href, l: childObj.level, d: curDeep }
// 记录当前映射项
!isFindMap && maps.push(mapItem)
if (arr.length) {
/**
* 只有第一个判断条件 (childObj.level > parentObj.level) 才进行 push 操作
* 其余条件则执行递归,直到当前子确实大于当前父,为父子关系
*/
if (childObj.level > parentObj.level) {
// 子等级大于父等级,即为父的子
parentObj.children.push(childObj)
// 每push一层,curDeep 就要增加 1,作为当前 childObj 的 deep 层数
mark.curDeep++
// 并且,当前子,作为下次的父
mark.parentObj = childObj
// 修改当前映射的 d 等于当前 deep 层数
mapItem.d = mark.curDeep
} else if (childObj.level < parentObj.level) {
// 子等级小于父等级,即子 deep 层级比当前父大(即当前子可能是当前父的父...)
// 映射数组从右向左,找到最接近并且小于当前子等级的映射项
const p = maps.reverse().find(item => item.l < childObj.level)
// reverse 会改变原数组,所以需要再次执行,还原顺序,这样后继 push 操作才不会有问题
maps.reverse()
if (p) {
// 找到的映射项,则把其 deep 层级,作为 targetDeep,初始 curDeep,开始递归
mark.targetDeep = p.d
mark.curDeep = 0
return recursive(arr, childObj)
} else {
// 如果找不到父,说明是最顶级,直接push
arr.push(childObj)
}
} else {
// 如果当前子的等级 等于 当前父的等级,说明它俩是同级,同父
// 目标层为当前层-1
mark.targetDeep = curDeep - 1
// 重置当前层
mark.curDeep = 0
// 递归
return recursive(arr, raw)
}
} else {
// 空数组,直接push
arr.push(childObj)
// push后,进入下一层
mark.curDeep++
// 当前子,作为下次的父
mark.parentObj = childObj
// 修改当前映射的 d 等于当前 deep 层数
mapItem.d = mark.curDeep
}
}
}
forEachArr(arr)
function forEachArr(arr) {
if (!Array.isArray(arr) || !arr.length) return
arr.forEach((item, i) => {
recursive(newArr, item, true)
})
}
console.log('>>>>>>>>>>>', newArr, maps, mark)
console.log(arr.length)
console