【JavaScript】 获取树被选中的顶级节点(小记)

1. 若存在一棵树

例如:

const tree = [
        {
            id: '1',
            children: [
                {
                    id: '1-1',
                    children: [
                        {
                            id: '1-1-1',
                            children: [
                                {
                                    id: '1-1-1-1',
                                    children: []
                                },
                                {
                                    id: '1-1-1-2',
                                    children: []
                                },
                                {
                                    id: '1-1-1-3',
                                    children: []
                                }
                            ]
                        }
                    ]
                },
                {
                    id: '1-2',
                    children: [
                        {
                            id: '1-2-1',
                            children: []
                        }
                    ]
                }
            ]
        },
        {
            id: '2',
            children: [
                {
                    id: '2-1',
                    children: [
                        {
                            id: '2-1-1',
                            children: []
                        }
                    ]
                },
                {
                    id: '2-2',
                    children: [
                        {
                            id: '2-2-1',
                            children: []
                        }
                    ]
                }
            ]
        }
    ]

2. 期望结果

     lookAtCheckedTopNodes(['1', '2'], tree) // => ['1', '2']
     lookAtCheckedTopNodes(['1-1-1-1', '1-1-1-2', '1-1-1-3'], tree) // => ['1-1']
     lookAtCheckedTopNodes(['1-1-1-1', '1-1-1-2', '1-1-1-3', '1-2'], tree) // => ['1']
     lookAtCheckedTopNodes(['1-1-1-1', '1-1-1-2', '1-1-1-3', '1-2-1'], tree) // => ['1']
     lookAtCheckedTopNodes(['1-1', '1-2'], tree) // => ['1']

3. 实现

function getCheckNodeAndParent(checked = [], tree = []) {
  const loop = (tree, parent = null, map = {}) => {
    for (const item of tree) {
      item.parent = parent
      if (checked.includes(item.id)) {
        map[item.id] = item
        continue
      }
      if (item.children && item.children.length) {
        const newMap = loop(item.children, item, map)
        map = { ...map, ...newMap }
      }
    }
    return map
  }
  return loop(tree)
}

function loopLookParent(map) {
  // 递归重新遍历map,找到所有的父节点
  const newMap = {}
  let flag = false
  for (const key in map) {
    const item = map[key]
    const { parent } = item
    if (!parent) {
      newMap[key] = item
      continue
    }
    const { id, children } = parent
    const parentChildrenCheckedAll = children?.every((child) => map[child.id])
    if (parentChildrenCheckedAll) {
      flag = true
      newMap[id] = parent
    } else {
      newMap[key] = item
    }
  }
  if (flag) {
    return loopLookParent(newMap)
  }
  return newMap
}

export function lookAtCheckedTopNodes(checked = [], tree = []) {
  const map = getCheckNodeAndParent(checked, tree)
  return loopLookParent(map)
}
posted @ 2024-05-24 15:25  demo_you  阅读(64)  评论(0编辑  收藏  举报