js算法问题,各位大佬留步看下有没有简洁的办法

有没有简单的方法来实现底下需求:

在list中找到id为7的值以及父级:

let list = [
   {
        id: 1,
    name: '测试1'
    children: [{id:2, name: '测试2'}, {id: 3, name: '测试3'}]
   },

   {
     id: 4,
     name: '测试4',
     children: [
       {id:5, name: '测试5'},
       {
          id:6, 
          name: '测试6',
          children[{id:7,name:'测试7'}]
       }
      ]
   }
    
]

查找节点id为7的一条链,要求输出结果为
[4,6,7]

求问各路大神,有没有什么比较代码简洁的方法?

阅读 5.2k
8 个回答
function findPathAll(tree, func) {
  const path = [];
  const list = [...tree];
  const result = [];
  const visited = new Set();
  const children = "children";
  while (list.length) {
    const node = list[0];
    if (visited.has(node)) {
      path.pop();
      list.shift();
    } else {
      visited.add(node);
      node[children] && list.unshift(...node[children]);
      path.push(node);
      func(node) && result.push(...path);
    }
  }
  return result;
}
let result = findPathAll(list, (item) => item.id === 7).map(item => item.id);

https://codepen.io/sugar710/pen/mdmMzyx?editors=1111

代码主要来源: vue-vben-admin

var list = [
   {
        id: 1,
    name: '测试1',
    children: [{id:2, name: '测试2'}, {id: 3, name: '测试3'}]
   },

   {
     id: 4,
     name: '测试4',
     children: [
       {id:5, name: '测试5'},
       {
          id:6, 
          name: '测试6',
          children:[{id:7,name:'测试7'}]
       }
      ]
   }
    
]
function treeLinkIds (list,id){
var ids =[];
var findTree = (list,id)=>list.find(item=>{
var flag = (id == item.id) || (item.children && findTree(item.children, id));
    flag && ids.push(item.id);
    return flag;
});
findTree(list,id);
return ids.reverse();
}
treeLinkIds(list,7);

结果
[4, 6, 7]

  const list = [
    {
      id: 1,
      name: '测试1',
      children: [
        { id: 2, name: '测试2' },
        { id: 3, name: '测试3' }
      ]
    },

    {
      id: 4,
      name: '测试4',
      children: [
        { id: 5, name: '测试5' },
        {
          id: 6,
          name: '测试6',
          children: [{ id: 7, name: '测试7' }]
        }
      ]
    }
  ]

  const fun = (node, id, nodeList = [], first = []) => {
    if (node) {
      for (const chData of node) {
        if (first.length == 0) {
          // 没有值就存第一次的值
          for (const firstNode of node) {
            first.push(firstNode.id)
          }
        } else {
          for (const firstData of first) {
            // 判断是不是第一次
            if (chData.id == firstData) {
              nodeList = []
            }
          }
        }
        nodeList.push(chData.id)
        if (chData.id == id) {
          return console.log(nodeList)
        }

        if (!chData.children) {
          if (nodeList.length > 0) {
            nodeList.splice(nodeList.length - 1)
          }
        }
        fun(chData.children, id, nodeList, first)
      }
    }
  }
  fun(list, 7)
type Item = {
  id: number
  name: string
  children?: Item[]
}
function ItemPath(list: Item[], id: Item['id']): Item['id'][] {
  for (const item of list) {
    if (item.id === id) {
      return [item.id]
    } else if (item.children) {
      const path = ItemPath(item.children, id)
      if (path.length !== 0) {
        return [item.id, ...ItemPath(item.children, id)]
      } else {
        continue
      }
    }
  }
  return []
}
console.log(ItemPath(list, 7))
function searchNodePath(arr, nodeId) {
  let result = [];

  function travelChildren(child, fn, ids, targetId) {
    if (child.id === targetId) {
      fn([...ids, child.id]);
      return;
    }

    (child.children || []).forEach((subChild) =>
      travelChildren(subChild, fn, [...ids, child.id], targetId),
    );
  }

  list.forEach((item) => {
    travelChildren(item, (ids) => (result = ids), [], nodeId);
  }, []);

  return result;
}

console.log(searchNodePath(list, 7));
新手上路,请多包涵
const findListById = (arr, id, res = []) => ((find = (arr, id, res) => arr && arr.some(item => (item.id === id || find(item.children, id, res)) && !!res.unshift(item.id)))(arr, id, res), res)
console.log(findListById(list, 7));
//[ 4, 6, 7 ]
/**
 * 
 * @param {Array} list 迭代的数组 list 或 children
 * @param {Number} pid 父节点的id,第一次迭代pid是undefined 
 * @returns {Array} result 要返回的结果
 */
function recursion(list, pid, result = []) {
    for (const item of list) {
        // 如果 当前节点的id是7,那么把id和父节点id添加到result中
        if (item.id === 7) {
            result.unshift(item.id)
            result.unshift(pid)
            return
        }
        // 如果不是 7,而且有children 那么迭代 children数组,并且把当前节点作为children的父节点 传下去
        else if (item.children) {
            recursion(item.children, item.id, result);
        }
        // 这一步很重要:如果 找到了 节点为7的,那么节点7和父节点一定是等于当前节点id的,应当把 他也添加到result
        // 有一种情况例外是第一轮,因为顶层的pid是undefined,所以不会添加到result
        if (result.includes(item.id) && pid) {
            result.unshift(pid)
        }
    }
    return result;
}

const result = recursion(list)
console.log(result)
推荐问题