这两天遇到一个数组转成树形结构的面试题

742 阅读1分钟

把下面数组转换成树形结构。

const list = [
  { parentId: '1', id: '11', value: ''},
  { parentId: '', id: '1', value: ''},
  { parentId: '1', id: '2', value: ''},
  { parentId: '3', id: '3-1', value: ''},
  { parentId: '1', id: '3', value: ''},
  { parentId: '2', id: '4', value: ''},
  { parentId: '3', id: '5', value: ''},
  { parentId: '4', id: '6', value: ''},
  { parentId: '', id: '7', value: ''},
  { parentId: '3', id: '8', value: ''},
  { parentId: '8', id: '9', value: ''},
  { parentId: '7', id: '10', value: ''},
];

最终结果

{
  1 : {
    child: {
      2: {
        child: {
          4: {
            child: {
              6: {}
            }
          }
        }
      },
      3: {
        child: {
          8: {}
        }
      }
    }
  },
  7: {

  }
}

解决思路:递归,记录索引

索引作用:通过parentId可以快速拿到所有父级ID,

{
  '1': [ '1' ],
  '2': [ '1', '2' ],
  '3': [ '1', '3' ],
  '4': [ '1', '2', '4' ],
  '5': [ '1', '3', '5' ],
  '6': [ '1', '2', '4', '6' ],
  '7': [ '7' ],
  '8': [ '1', '3', '8' ],
  '9': [ '1', '3', '8', '9' ],
  '10': [ '7', '10' ],
  '11': [ '1', '11' ],
  '3-1': [ '1', '3', '3-1' ]
}

完整代码

const data = {}; // 最终结果
const index = {}; // 索引 | 族谱
function tree(dataList) {
  const noIndexOfData = []; // 记录没有查找索引&&存在父级ID的数据
  dataList.map((v, k) => {
    if (index[v.parentId]) {
      indexOfAppend(data, v, index[v.parentId], 0); // 通过索引查找并创建或追加数据
      index[v.id] = [...index[v.parentId], v.id]; // 记录当前数据所有亲属关系 || [1, 2, 3, 4]
      return;
    }
    if (v.parentId) {
      noIndexOfData.push(v);
      return;
    }
    data[v.id] = v;
    index[v.id] = [v.id];
    return;
  })
  if (noIndexOfData.length > 0) {
    tree(noIndexOfData);
  }
}

// 通过索引查找父级数据
function indexOfAppend(resdata, appendData, index, num) {
  if (index[num] && resdata[index[num]] && resdata[index[num]].child) {
    if ((index.length - 1) === num) {
      const res = resdata[index[num]]["child"];
      res[appendData.id] = appendData;
      resdata[index[num]].child = res
      return;
    }
    indexOfAppend(resdata[index[num]].child, appendData, index, num + 1);
    return;
  } 
  if (index[num] && resdata[index[num]]) {
    const res = {};
    res[appendData.id] = appendData;
    resdata[index[num]] = {...resdata[index[num]], child: res}
  }
}

tree(list);
console.info(JSON.stringify(data), index)

索引也可以通过以下方式进行建立:

const data = {child: {b: 1}};
const index = {}
index['1'] = data.child;
index['1'].b = 2;
console.log(data, index);// data下的b结果是多少呢?
// 你懂得...