• 树形多级菜单数据源嵌套结构与扁平结构互转


    树形多级菜单数据源嵌套结构与扁平结构互转

    数据源格式

    一般来说,要想动态渲染树形菜单,这个样子的数据源格式对前端很友好。

    var data = [
    	{
        name: "父节点1",
        children: [
          {
            name: "子节点11",
            children:[
              {
                name: "叶子节点111",
                children:[]
              },
              {
                name: "叶子节点112",
                children:[]
              },
              {
                name: "叶子节点113",
                children:[]
              },
              {
                name: "叶子节点114",
                children:[]
              }
            ]
          }
         //...
        ]
      },
    ];
    

    问题

    在后端,这些数据通常是存储在关系型数据库中,后端开发将数据从数据库中取出来返回给前端的数据往往这样子的:

    const data =[
      { id:1,   pid:0,  name:"父节点1"     },           
      { id:11,  pid:1,  name:"父节点11"    },
      { id:111, pid:11, name:"叶子节点111" },
      { id:112, pid:11, name:"叶子节点112" },
      { id:113, pid:11, name:"叶子节点113" },
      { id:114, pid:11, name:"叶子节点114" },
      { id:12,  pid:1,  name:"父节点12"    },
      { id:121, pid:12, name:"叶子节点121" },
      { id:122, pid:12, name:"叶子节点122" },
      { id:123, pid:12, name:"叶子节点123" },
      { id:124, pid:12, name:"叶子节点124" },
      { id:13,  pid:1,  name:"父节点13"    },
      { id:2,   pid:0,  name:"父节点2"     },
      { id:21,  pid:2,  name:"父节点21"    },
      { id:211, pid:21, name:"叶子节点211" },
      { id:212, pid:21, name:"叶子节点212" },
      { id:213, pid:21, name:"叶子节点213" },
      { id:214, pid:21, name:"叶子节点214" },
      { id:22,  pid:2,  name:"父节点22"    },
      { id:221, pid:22, name:"叶子节点221" },
      { id:222, pid:22, name:"叶子节点222" },
      { id:223, pid:22, name:"叶子节点223" },
      { id:224, pid:22, name:"叶子节点224" },
      { id:23,  pid:2,  name:"父节点23"    },
      { id:231, pid:23, name:"叶子节点231" },
      { id:232, pid:23, name:"叶子节点232" },
      { id:233, pid:23, name:"叶子节点233" },
      { id:234, pid:23, name:"叶子节点234" },
      { id:3,   pid:0,  name:"父节点3"     }
    ];
    

    解决方案

    扁平转嵌套

    /**
     * 将一个普通的节点数组(带有指向父节点的指针)转换为嵌套的数据结构。
     * @param {*} data  一组数据
     * @param {*} option 包含以下字段的对象:
     *      parentProperty(String):可以找到父节点链接的属性的名称。默认值:'pid'。
     *      childrenProperty(String):将存储子节点的属性的名称。默认值:'children'。
     *      idProperty(String):唯一的节点标识符。默认值:'id'。
     *      nameProperty(String):节点的名称。默认值:'name'。
     */
    function FlatToNested(data, option) {
      option = option || {};
      let idProperty = option.idProperty || 'id';
      let parentProperty = option.parentProperty || 'pid';
      let childrenProperty = option.childrenProperty || 'children';
      let res = [],
        tmpMap = [];
      for (let i = 0; i < data.length; i++) {
        tmpMap[data[i][idProperty]] = data[i];
        if (tmpMap[data[i][parentProperty]] && data[i][idProperty] != data[i][parentProperty]) {
          if (!tmpMap[data[i][parentProperty]][childrenProperty])
            tmpMap[data[i][parentProperty]][childrenProperty] = [];
          tmpMap[data[i][parentProperty]][childrenProperty].push(data[i]);
        } else {
          res.push(data[i]);
        }
      }
      return res;
    }
    

    如果返回的数据和示例数据的字段不一致,那么您也无需更改源代码,方法提供了可配置选项,如下所示:

    例如,您收到这样的数据:

    const data =[
        { _id:1,   parentID:0,  text:"父节点1"     },           
        { _id:11,  parentID:1,  text:"父节点11"    },
        { _id:111, parentID:11, text:"叶子节点111" },
        { _id:112, parentID:11, text:"叶子节点112" },
        { _id:113, parentID:11, text:"叶子节点113" },
        { _id:114, parentID:11, text:"叶子节点114" },
        { _id:12,  parentID:1,  text:"父节点12"    },
        { _id:121, parentID:12, text:"叶子节点121" },
        { _id:122, parentID:12, text:"叶子节点122" }
        //...
      ];
    

    那么,您可以这样调用函数:

    FlatToNested(nodes,{
        idProperty:'_id',            //唯一的节点标识符。
        nameProperty:'text',         //节点的名称。
        parentProperty:'parentID',  //可以找到父节点链接的属性的名称。
        childrenProperty:'son'      //将存储子节点的属性的名称。
    })
    
    ### 嵌套转扁平
    
    ​```javascript
    /**
     * 嵌套型格式转扁平型格式
     * @param {Array} data 
     */
    function NestedToFlat(data,pid) { 
      var res = []
      for (var i = 0; i < data.length; i++) {
        res.push({
          id: data[i].id,
          name: data[i].name,
          pid: pid || 0
        })
        if (data[i].children) {
          res = res.concat(NestedToFlat(data[i].children, data[i].id));
        }
      }
      return res;
    }
    
  • 相关阅读:
    Java高级之类结构的认识
    14.8.9 Clustered and Secondary Indexes
    14.8.4 Moving or Copying InnoDB Tables to Another Machine 移动或者拷贝 InnoDB 表到另外机器
    14.8.3 Physical Row Structure of InnoDB Tables InnoDB 表的物理行结构
    14.8.2 Role of the .frm File for InnoDB Tables InnoDB 表得到 .frm文件的作用
    14.8.1 Creating InnoDB Tables 创建InnoDB 表
    14.7.4 InnoDB File-Per-Table Tablespaces
    14.7.2 Changing the Number or Size of InnoDB Redo Log Files 改变InnoDB Redo Log Files的数量和大小
    14.7.1 Resizing the InnoDB System Tablespace InnoDB 系统表空间大小
    14.6.11 Configuring Optimizer Statistics for InnoDB 配置优化统计信息用于InnoDB
  • 原文地址:https://www.cnblogs.com/ssaylo/p/14029273.html
Copyright © 2020-2023  润新知