树形数据操作

122 阅读2分钟
 created() {
    let tree = [
      {
        name: 1,
        level: 0,
        children: [
          {
            name: 1,
            level: 1,
            children: [
              { name: 1, level: 2, children: [{ name: 1, level: 3, children: [{ name: 1, level: 4, children: [] }] }] },{name: "测试", level: 2,children:[{name: "测试", level: 3,children:[]}]}
            ],
          },
        ],
      },
      { name: 2, levle: 0, children: [{ name: 1, level: 1, children: [] }] },
    ]
    let res = this.filterTree(tree)
    console.log(res)
  },
 filterTree(tree, arr = []) {
      if (!tree.length) return []
      for (let item of tree) {
        // 循环数组,然后过滤数据
        // 如果该条件满足时,跳出本次循环
        if (item.level == 3) continue
        // 如果满足条件时,用新node代替,然后把chilren清空
        let node = { ...item, children: [] }
        // 然后添加到新数组中
        arr.push(node)
        // 如果有子节点,调用递归函数,并把空数组传给下一个函数
        // 利用引用数据类型的特性,实现浅拷贝
        // 递归函数过滤时会改变这个空数组数据,从而实现层级结构过滤
        if (item.children && item.children.length) {
          this.filterTree(item.children, node.children)
        }
      }
      return arr
    },

结果

[
    {
        "name": 1,
        "level": 0,
        "children": [
            {
                "name": 1,
                "level": 1,
                "children": [
                    {
                        "name": 1,
                        "level": 2,
                        "children": []
                    },
                    {
                        "name": "测试",
                        "level": 2,
                        "children": []
                    }
                ]
            }
        ]
    },
    {
        "name": 2,
        "levle": 0,
        "children": [
            {
                "name": 1,
                "level": 1,
                "children": []
            }
        ]
    }
]
/**
 * 由于目前的组件事件无法返回父节点的数据所以需要该方法反查父节点
 * @param {*} data 要遍历的数据
 * @param {*} target 查找目标
 * @param {*} result 用于装查找结果的数组
 * @param {*} str   比对的一个键值
 * @returns
 */
function findParent(data, target, str, result) {
  for (let i in data) {
    let item = data[i];
    if (item[str] === target[str]) {
      //将查找到的目标数据加入结果数组中
      result.unshift(item.value);
      return true;
    }
    if (item.children && item.children.length > 0) {
      let ok = findParent(item.children, target, str, result);
      if (ok) {
        result.unshift(item.value);
        return true;
      }
    }
  }
  //走到这说明没找到目标
  return false;
}

function changeTreeKey(arr,before,after) {
  let str = JSON.stringify(arr); // arr是多维数组
  var reg = new RegExp(before, 'g'); //直接针对某个字符
  var newstr = str.replace(reg, after); //结果就是对应的全替换了
  return JSON.parse(newstr); //再转回数组就好了 完事
}

//去除最后一级子项的空children
function removeChildren(arr) {
  let childs = arr;
  for (let i = childs.length; i--; i > 0) {
    if (childs[i].children) {
      if (childs[i].children.length) {
        removeChildren(childs[i].children);
      } else {
        delete childs[i].children;
      }
    }
  }
  return arr;
}
export { findParent, removeChildren, changeTreeKey };


    //树状数据扁平化
    filterTree(tree, obj = {}) {
      return tree.reduce((res, item) => {
        const { children, ...i } = item
        if (obj) {
          i.pid = obj.path
        } else {
          i.pid = ''
        }
        return res.concat(i, children && children.length ? this.filterTree(children, i) : [])
      }, [])
    },

    //扁平转树
    transData(a, idStr, pidStr, chindrenStr) {
      var r = [],
        hash = {},
        id = idStr,
        pid = pidStr,
        children = chindrenStr,
        i = 0,
        j = 0,
        len = a.length
      for (; i < len; i++) {
        hash[a[i][id]] = a[i]
      }
      for (; j < len; j++) {
        var aVal = a[j],
          hashVP = hash[aVal[pid]]
        if (hashVP) {
          !hashVP[children] && (hashVP[children] = [])
          hashVP[children].push(aVal)
        } else {
          r.push(aVal)
        }
      }
      return r
    },