扁平数组转树形结构的几种实现

Posted 小蜗牛

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了扁平数组转树形结构的几种实现相关的知识,希望对你有一定的参考价值。

输入source:

[
    {
        id: 1,
        pid: 0,
        name: \'body\'
    }, {
        id: 2,
        pid: 1,
        name: \'title\'
    }, {
        id: 3,
        pid: 2,
        name: \'div\'
    },
    {
        id: 4,
        pid: 0,
        name: \'div\'
    },
    {
        id: 9,
        pid: 4,
        name: \'div\'
    }
]

输出:

[
    {
        id: 1,
        pid: 0,
        children: [
          {
             id: 2,
             pid: 1,
             children: [
                {
                  id: 3,
                  pid: 2,

                }
             ]
          }
        ]
    },{
        id: 4,
        pid: 0,
        children: [
         {
           id: 9,
           pid: 4
         }
        ]

    }
]

实现1:

function  fn(data) {
    let map = {};
    let result = [];
    // 存映射,方便取值
    data.forEach((el) => {
        map[el.id] = el;
    });
    data.forEach((item) => {
        const father = map[item.pid];
        if (father) {
            (father.children || (father.children = [])).push(item);
        } else {
            result.push(item);
        }
    });

    return result;
}
fn(source)

实现2:

function lookupChildren (target) {
    let source = JSON.parse(JSON.stringify(target))
    let newAry = []
    let i = 0
    while (i < source.length) {
        let _pitem = source[i]
        // 找当前项所有子节点
        let _ch = source.filter(item => item.pid === _pitem.id)
        let _father = source.find(item => _pitem.pid === item.id)
        _pitem.children = _ch
        !_father && newAry.push(_pitem)
        i++
    }
    return newAry
}
lookupChildren(source)

实现3:

// 找出根节点
let root = source.filter(({ pid }) => !source.find((item) => (item.id === pid)))
const getChilds = (list) => {
    return list.map(item => {
        let children = source.filter((temp) => temp.id === item.pid)
        item.children = getChilds(children)
        return item
    })
}
getChilds(root)

实现4:

const idMapping = source.reduce((acc, el, i) => {
  acc[el.id] = i;
  return acc;
}, {});
let root;
source.forEach(el => {
  // 判断根节点
  if (el.parentId === null) {
    root = el;
    return;
  }
  // 用映射表找到父元素
  const parentEl = data[idMapping[el.pid]];
  // 把当前元素添加到父元素的`children`数组中
  parentEl.children = [...(parentEl.children || []), el];
});

以上是关于扁平数组转树形结构的几种实现的主要内容,如果未能解决你的问题,请参考以下文章

JavaScript 扁平与树形数组数据的转换

JavaScript实现扁平数组结构与JSON树形结构相互转换递归reducecontinuepushconcatfor of

浅理解扁平数据结构转Tree(树形结构)

js把树形数据转成扁平数据

JavaScript扁平数组结构转换成JSON树形结构无限极forEachpushchildren

JavaScript实现树形扁平化(数组降维)