JS知识回顾(七):数组与树

64 阅读1分钟

1.数组转化为树结构

数据示例:

   /** 数组结构数据arrayData */
   const arrayData = [
    { id: 2, title: '中国', parent_id: 0 },
    { id: 3, title: '广东省', parent_id: 2 },
    { id: 4, title: '广州市', parent_id: 3 },
    { id: 5, title: '天河区', parent_id: 4 },
    { id: 6, title: '湖南省', parent_id: 2 },
    { id: 1, title: '俄罗斯', parent_id: 0 }
   ]

方法一:

/**
 * 一维数组转化为树
 * @param {数组数据} list
 * @param {父id} parent_id
 * @returns
 */
export const listToTree = (list: MenuItemOptions[]): MenuItemOptions[] => {
  list.forEach((node) => {
    const pNode = list.find((row) => row.id === node.parent_id)
    if (pNode) {
      pNode.children = pNode.children || []
      pNode.children.push(node)
    }
  })

  return list.filter((node) => `${node.parent_id}` === 0)
}

// 方法调用
console.log('数组转树', listToTree(arrayData))

方法二:

/**
 * 递归查找添加children
 * @param {数组数据} data
 * @param {存放返回结果} result
 * @param {父id} pid
 */

export const arrayToTree = (data: any, pid: any) => {
  const result:any = []
  /**
 * 转化方法
 * @param {数组数据} data
 * @param {父id} pid
 * @returns
 */
  const getChildren = (data: any, result: any, pid: any): any => {
    for (const item of data) {
      if (item.parent_id === pid) {
        const newItem = { children: [], ...item }
        result.push(newItem)
        getChildren(data, newItem.children, item.id)
      }
    }
  }
  getChildren(data, result, pid)
  return result
}

// 方法调用
console.log(arrayToTree(arrayData, 0))

2.树转化为数组(树的扁平化)

数据示例:

  /** 树状形结构数据treeData */
const treeData = [
  {
    id: 2, title: '中国', parent_id: 0,
    children: [
      {
        id: 3, title: '广东省', parent_id: 2,
        children: [
          {
            id: 4, title: '广州市', parent_id: 3,
            children: [
              { id: 5, title: '天河区', parent_id: 4 }
            ]
          }
        ]
      },
      { id: 6, title: '湖南省', parent_id: 2 }
    ]
  },
  { id: 1, title: '俄罗斯', parent_id: 0, },
]

方法一:

/**
 * 树转一维数组
 * @param tree
 * @returns res
 */
export const treeToList = (tree: any) => {
  const res: any[] = []
  const dfs = (tree: any) => {
    tree.forEach((item: any) => {
      if(item.children) {
        dfs(item.children)
        delete item.children
      }
      res.push(item)
    })

  }
  dfs(tree)
  return res
}

// 方法调用
console.log('树转数组', treeToList(treeData))

方法二:

/**
 * 树转一维数组
 * @param arr
 * @returns result
 */
export const flatten = (arr: any) => {
  let result: any[] = []
  arr.forEach((item: any) => {
    if(Array.isArray(item?.children)) {
      result = result.concat(flatten(item.children))
      const newItem = {
        ...item
      }
      delete newItem.children
      result.push(newItem)
    } else {
      result.push(item)
    }
  })
  return result
}

// 方法调用
console.log('树转数组', flatten(treeData))

3. Tree 查找路径(id)

根据id查找所在目录路径

数据示例:

  /** 树状形结构数据treeData */
const treeData = [
  {
    id: 2, title: '中国', parent_id: 0,
    children: [
      {
        id: 3, title: '广东省', parent_id: 2,
        children: [
          {
            id: 4, title: '广州市', parent_id: 3,
            children: [
              { id: 5, title: '天河区', parent_id: 4 }
            ]
          }
        ]
      },
      { id: 6, title: '湖南省', parent_id: 2 }
    ]
  },
  { id: 1, title: '俄罗斯', parent_id: 0, },
]
/**
 * 根据id查找所在目录路径
 * @param {树结构的数组数据} tree
 * @param {要查找的id} id
 * @param {初始路径} path
 * @returns
 */

export function parseTreePath(tree: any, id: any, path = '') {
  let result: any = ''
  tree.forEach((node: any) => {
    let tempPath = path

    // 避免出现在最前面的
    tempPath = `${tempPath ? tempPath + '/' : tempPath}${node.title}`
    if(node.id == id) result = tempPath
    else if(node.children) {
      const sNode: any = parseTreePath(node.children, id, tempPath)
      if(sNode)  result = sNode
    }
  })
  return result
}

// 方法调用
console.log('路径', parseTreePath(treeData, 5))

/**
 * 根据id查找所在目录路径
 * @param {树结构的数组数据} tree
 * @param {要查找的id} id
 * @param {初始路径} path
 * @returns
 */
export function parseTreePath1(tree: any, id:any, path = "") {
  for (let i = 0; i < tree.length; i++) {
    let tempPath = path
    // 避免出现在最前面的/
    tempPath = `${tempPath ? tempPath + "/ " : tempPath}${tree[i].title}`
    if (tree[i].id == id) return tempPath
    else if (tree[i].children) {
      const reuslt: any = parseTreePath(tree[i].children, id, tempPath)
      if (reuslt) return reuslt
    }
  }
}