繁体   English   中英

如何将平面数据结构转换为树状结构?

[英]How to convert a flat data structure into a tree-like structure?

假设我有两个辅助函数将{}的平面数组转换为树状结构。 考虑以下平面数据:

const data = [
     {
            "ID": 1,
            "Tier_1": "DataSource1",
            "Tier_2": "Area",
            "Tier_3": "General",
        },
        {
            "ID": 2,
            "Tier_1": "DataSource1",
            "Tier_2": "Financial",
            "Tier_3": "General",
        },
        {
            "ID": 3,
            "Tier_1": "DataSource1",
            "Tier_2": "Area",
            "Tier_3": "General",
        },
        {
            "ID": 4,
            "Tier_1": "DataSource2",
            "Tier_2": "Area",
            "Tier_3": "General",
        },
        {
            "ID": 5,
            "Tier_1": "DataSource2",
            "Tier_2": "Area",
            "Tier_3": "Management Plan",
        }
]

数据包含三行某些分层信息,我想将其转换为树状结构,如下所示(预期输出):

(最后的子节点是实际的DB对象,但是在树上分布)

const output = {
  "DataSource1: {
    "Area": {
        {
            "ID": 1,
            "Tier_1": "DataSource1",
            "Tier_2": "Area",
            "Tier_3": "General",
        },
        {
            "ID": 3,
            "Tier_1": "DataSource1",
            "Tier_2": "Area",
            "Tier_3": "General",
        },
      },
      "Financial": [
        {
            "ID": 2,
            "Tier_1": "DataSource1",
            "Tier_2": "Financial",
            "Tier_3": "General",
        },
      ]
  },
  "DataSource2: {
      "Area": [
          {
            "ID": 4,
            "Tier_1": "DataSource2",
            "Tier_2": "Area",
            "Tier_3": "General",
          },
          {
            "ID": 5,
            "Tier_1": "DataSource2",
            "Tier_2": "Area",
            "Tier_3": "Management Plan",
          }
       ]
      }
  }
}

我实际上设法创建功能来完成这个,但我不是那么灵活(深度/暗淡是固定的,在每个函数名称中说明)

函数返回二维树:

const getDataCategoriesTwoDim = (data, mainCategory) => {
  const dataFields = [...data];
  let map = {};

  for (let i = 0; i < dataFields.length; i += 1) {
    const currentField = dataFields[i];
    const currentCategory = currentField[mainCategory];

    if (!map[currentCategory]) {
      map[currentCategory] = [];
    }
    map[currentCategory].push(currentField);
  }

  return map;
};

函数返回三维树:

const getDataCategoriesThreeDim = (data, mainCategory, subCategory) => { // DIFF
  const dataFields = [...data];
  let map = {};

  for (let i = 0; i < dataFields.length; i += 1) {
    const currentField = dataFields[i];
    const currentCategory = currentField[mainCategory];
    const currentSubcategory = currentField[subCategory]; // DIFF

    if (!map[currentCategory]) {
      map[currentCategory] = {}; /DIFF
    }
    if (!map[currentCategory][currentSubcategory]) { // DIFF
      map[currentCategory][currentSubcategory] = []; // DIFF
    } // DIFF
    map[currentCategory][currentSubcategory].push(currentField); // DIFF
  }

  return map;
};

你可以这样调用这两个并得到预期的结果:

  getDataCategoriesTwoDim(data, 'Tier_2');
  getDataCategoriesThreeDim(data, 'Tier_2', 'Tier_3');

正如您所看到的,有很多代码重复和复制粘贴。 我在评论中标出了差异。 如何将代码重写为一个函数,以便我可以设置2,3或更多维度?

您可以使用键来嵌套属性,并为最后一个键而不是对象添加数组。 稍后将对象推送到嵌套数组。

 const groupBy = (data, keys) => data.reduce((r, o) => { keys .reduce((p, k, i, a) => p[o[k]] = p[o[k]] || (i + 1 === a.length ? [] : {}), r) .push(o); return r; }, Object.create(null)), data = [{ ID: 1, Tier_1: "DataSource1", Tier_2: "Area", Tier_3: "General" }, { ID: 2, Tier_1: "DataSource1", Tier_2: "Financial", Tier_3: "General" }, { ID: 3, Tier_1: "DataSource1", Tier_2: "Area", Tier_3: "General" }, { ID: 4, Tier_1: "DataSource2", Tier_2: "Area", Tier_3: "General" }, { ID: 5, Tier_1: "DataSource2", Tier_2: "Area", Tier_3: "Management Plan" }], result1 = groupBy(data, ["Tier_1", "Tier_2"]), result2 = groupBy(data, ["Tier_1", "Tier_2", "Tier_3"]); console.log(result1); console.log(result2); 
 .as-console-wrapper { max-height: 100% !important; top: 0; } 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM