二维数组转换树状结构

2,447 阅读1分钟

题目

  • 二维数组:
[
  ['hello', 'hill'],
  ['hello', 'jack'],
  ['world', 'foo', 'jerry'],
  ['world', 'foo', 'peter', 'tom'],
  ['world', 'bar']
]
  • 转换后的树状结构图
[
  {
    "name": "hello",
    "id": "01",
    "child": [
      {
        "id": "0101",
        "name": "hill"
      },
      {
        "id": "0102",
        "name": "jack"
      }
    ]
  },
  {
    "name": "world",
    "id": "02",
    "child": [
      {
        "name": "foo",
        "id": "0201",
        "child": [
          {
            "id": "020101",
            "name": "jerry"
          },
          {
            "id": "020102",
            "name": "peter",
            "child": [
              {
                "id": "02010201",
                "name": "tom"
              }
            ]
          }
        ]
      },
      {
        "id": "0202",
        "name": "bar"
      }
    ]
  }
]
  • 代码
/**
 *
 * @param {array} a 需转换数组
 */
function madeTree(a) {
  /**
   *
   * @param {string} s 父级id
   * @param {number} n 需转换数字
   */
  const getId = (s, n) => (n < 10 ? `${s}0${n}` : `${s}${n}`)

  /**
   * 递归转换函数
   * @param {array} c 当前需转换数组
   * @param {array} p 目标数组
   * @param {string} pId 父级id
   */
  const g = (c, p = [], pId = '') => {
    if (!Array.isArray(c) || c.length === 0) {
      return p
    }
    // 递归取出第一个元素操作
    const [first, ...other] = c
    const fIndex = p.findIndex(
      item => typeof item === 'object' && item.name === first
    )
    if (fIndex > -1) {
      const { child = [], id, ...oTemp } = p[fIndex]
      if (other.length > 0) {
        p[fIndex] = { ...oTemp, id, child: g(other, child, id) }
      }
    } else {
      const cId = getId(pId, p.length + 1)
      const childObj = other.length > 0 ? { child: g(other, [], cId) } : {}
      p.push({
        id: cId,
        name: first,
        ...childObj
      })
    }
    return p
  }
  return a.reduce((pre, curr, index) => {
    return g(curr, pre)
  }, [])
}

const source = [
  ['hello', 'hill'],
  ['hello', 'jack'],
  ['world', 'foo', 'jerry'],
  ['world', 'foo', 'peter', 'tom'],
  ['world', 'bar']
]
console.log(JSON.stringify(madeTree(source), null, 2))
该内容临时记录