前端数据处理杂项记

94 阅读2分钟
  • 用来记录数据处理相关的东西和 七七八八八的杂事问题
  • 😁🤣😄😳走起

数据相关

递归部门总工资

  • 递归会暂停执行当前函数,待递归调用处理完毕得出结果后再恢复执行上下文
// 数据
let numArr = {
  sales: [
    { name: "John", salary: 1000 },
    { name: "Alice", salary: 1600 },
  ],

  development: {
    sites: [
      { name: "Peter", salary: 2000 },
      { name: "Alex", salary: 1800 },
    ],
    internals: [{ name: "Jack", salary: 1300 }],
  },
};

// 要求计算公司所有部门的工资总和
function sumSalary(salary) {
    // 如果是数组正常累加即可
    if(Array.isArray(salary)) {
     return salary.reduce((prev, curr) => {
         return prev + curr.salary;
     }, 0)
    } else{
      let sum = 0;
      // 如果不是一个数组-需要Object.values 转换并递归
      for(let k of Object.values(salary)) {
        sum += sumSalary(k)
      }
      
      return sum;
    }
}

树形数据扁平化

  • 将一组树形化结构数据转为扁平化数组
 // 数据
 let data = [
    {
      id: 1,
      name: "a",
      children: [
        { 
          id: 12, name: "aa", 
          children: [ 
          { id: 121, name: "aaa", }, { id: 122, name: "aab", }, 
        ],
       },
        { 
          id:13, name: 'bb', 
          children:[
             { id: 131, name: 'bbb' } 
            ] }
      ],
    },
  ];
  
  // 这里假设后端没有给接口 设置pid, 我们可以手动添加一项
  let result = data.reduce(function((prev, curr)) {
    prev.push({
      id: curr.id,
      name: curr.id,
      pid: curr.pid || 0
    })
    
    // 若当前项存在 children -> 遍历它
    curr.children && curr.children.forEach((v) => {
       v.pid = curr.id; // 让子元素的pid 确定从属关系
       arguments.callee(prev, k); // 递归
    })
    
    return prev;
  }, [])
    

扁平化数据转树形化

  • 根据上面的树形化数据转扁平化数组,可以继续将扁平化数据转成树形结构
 假设接上面的扁平化数据结果result,可以这样处理
 function trees(arr, id = 0) {
  return arr.filter(item => {
   // 如果当前项的pid == 0 说明它就是最大的父级
   if(item.pid === id) {
      // 递归-添加子级
      item.children = trees(arr, item.id)
      return true;
   }
  })
 }

树形数据的字段替换

需求:将树形结构数据 比如公司部门层级:的name 更换成 label, 子级nodes 更换成 children

// 树形数据
let treeData = [
  {
    id: 1,
    pid: null,
    name: "研发部",
    nodes: [
      { id: 3, pid: 1, name: "前端研发部" },
      { id: 4, pid: 1, name: "后端研发部" },
    ],
  },

  {
    id: 2,
    pid: null,
    name: "管理部",
    nodes: [{ id: 5, pid: 2, name: "行政管理部" }],
  },

  { id: 6, pid: null, name: "财务部" },
];

// 先定义一个映射对象
let propsMap = {
    name: 'label',
    nodes: 'children'
}

// 树形数据-属性转换函数
function treeDatas(treeData, propsMap) {
  return treeData.reduce((sum, cur) => {
    let obj = ((cur, propsMap) => {
      return Object.keys(cur).reduce((prev, key) => {
        // 空对象prev里面有没有label字段, 有就用映射对象的值(label || children)替换 z再赋值,没有就 直接添加属性和值
        prev[propsMap[key] ? propsMap[key] : key] = cur[key];
        return prev;
      }, {});
    })(cur, propsMap);

    // 有子节点-> 递归
    if (cur.nodes) {
      let nodes = treeDatas(cur.nodes, propsMap);
      console.log(nodes)

      obj[propsMap.nodes ? propsMap.nodes : "children"] = nodes;
    }
    sum.push(obj);

    return sum;
  }, []);
}


// 调用
let result = treeDatas(treeData, propsMap);

// 输出
console.log(result);