如何将原始数据转换为层次结构

How to convert a raw data into hierarchical structure

我有来自数据库 table 的原始数据,它们之间没有直接关系。但是我有一组键,它为我们提供了数据中层次结构的顺序。

尝试了类似 的方法。但无法获得所需的输出。

输入数据

const data = {
  item1: {
    chancellor: "my-chancellor-1",
    viceChancellor: "my-vice-chancellor-1",
    headProfessor: "my-head-professor-1",
    student: "student-1",
    intern: null,
  },
  item2: {
    chancellor: "my-chancellor-1",
    viceChancellor: "my-vice-chancellor-1",
    headProfessor: "my-head-professor-1",
    student: null,
    intern: null,
  },
  item3: {
    chancellor: "my-chancellor-1",
    viceChancellor: "my-vice-chancellor-1",
    headProfessor: "my-head-professor-1",
    student: "student-2",
    intern: null,
  },
  item4: {
    chancellor: "my-chancellor-1",
    viceChancellor: "my-vice-chancellor-1",
    headProfessor: "my-head-professor-1",
    student: "student-3",
    intern: "intern-1",
  },
}

正如我所说,我们有标识层次结构的键。 假设 键是

const keyArray = ["chancellor", "viceChancellor", "headProfessor", "student", "intern"]

我们如何获得层次结构的输出?

输出

[
  {
    keyName: "chancellor",
    name: "my-chancellor-1",
    children: [
      {
        keyName: "viceChancellor",
        name: "my-vice-chancellor-1",
        children: [
          {
            keyName: "headProfessor",
            name: "my-head-professor-1",
            children: [
              {
                keyName: "student",
                name: "student-1",
              },
              {
                keyName: "student",
                name: "student-2",
              },
              {
                keyName: "student",
                name: "student-3",
                children: [
                  {
                    keyName: "intern",
                    name: "intern-1",
                  },
                ],
              },
            ],
          },
        ],
      },
    ],
  },
];

请找到解决方案,它有点冗长,因为我没有使用任何ES6功能。但它在逻辑上仍然按预期工作。

const data = {
  item1: {
    chancellor: "my-chancellor-1",
    viceChancellor: "my-vice-chancellor-1",
    headProfessor: "my-head-professor-1",
    student: "student-1",
    intern: null,
  },
  item2: {
    chancellor: "my-chancellor-1",
    viceChancellor: "my-vice-chancellor-1",
    headProfessor: "my-head-professor-1",
    student: null,
    intern: null,
  },
  item3: {
    chancellor: "my-chancellor-1",
    viceChancellor: "my-vice-chancellor-1",
    headProfessor: "my-head-professor-1",
    student: "student-2",
    intern: null,
  },
  item4: {
    chancellor: "my-chancellor-1",
    viceChancellor: "my-vice-chancellor-1",
    headProfessor: "my-head-professor-1",
    student: "student-3",
    intern: "intern-1",
  },
};
const keyArray = ["chancellor", "viceChancellor", "headProfessor", "student", "intern"]

let output = [];
let parent = null;

Object.keys(data).forEach(dk => {
  parent = output.find(el => el.name == data[dk][keyArray[0]]);
  keyArray.forEach(kele => {
    if (!data[dk][kele]) {
      return;
    }
    let child = {
      "keyName": kele,
      "name": data[dk][kele]
    };
    if (!parent) {
      output.push(child);
      parent = child;
    } else {
      if (!parent.children)
        parent.children = [];
      let alreadyPresentChild = parent.children.find(chl => chl.name == child.name);
      if (parent.keyName != child.keyName) {
        if (!alreadyPresentChild) {
          parent.children.push(child);
          parent = child;
        } else {
          parent = alreadyPresentChild;
        }
      }
    }

  });
});

console.log(JSON.stringify(output));

您可以按如下方式构建层次结构。通过保留一个映射,以路径为键,您可以快速检查您是否已经有一个当前值的节点,或者需要创建一个并将其添加到父节点的子节点列表中:

function createHierarchy(data) {
    let tree = { children: [] };
    let keys = {};
    for (let item of Object.values(data)) {
        let node = tree;
        let key = "";
        for (let keyName of ["chancellor", "viceChancellor", "headProfessor", "student", "intern"]) {
            let name = item[keyName];
            if (name == null) break;
            key += "/" + name;
            let child = keys[key]; // Fast lookup
            if (!child) {
                child = keys[key] = { keyName, name };
                (node.children ??= []).push(child);
            }
            node = child;
        }
    }
    return tree.children;
}

// Demo
const data = {item1: {chancellor: "my-chancellor-1",viceChancellor: "my-vice-chancellor-1",headProfessor: "my-head-professor-1",student: "student-1",intern: null,},item2: {chancellor: "my-chancellor-1",viceChancellor: "my-vice-chancellor-1",headProfessor: "my-head-professor-1",student: null,intern: null,},item3: {chancellor: "my-chancellor-1",viceChancellor: "my-vice-chancellor-1",headProfessor: "my-head-professor-1",student: "student-2",intern: null,},item4: {chancellor: "my-chancellor-1",viceChancellor: "my-vice-chancellor-1",headProfessor: "my-head-professor-1",student: "student-3",intern: "intern-1",},};

console.log(createHierarchy(data));