有许多解决方案可以使用 JavaScript 从基于数字引用 ID 的平面数组构建树数组。但我找不到任何解决方案来创建基于字母数字 ID 和日期进行排序的树数组。
我有许多讨论消息存储在一个平面数组中(见下文)。我需要从中创建一个树数组,所有子项都按日期排序。这样整个讨论(包括初始消息以及对讨论线程中各种消息的回复)的消息顺序都是正确的,因为它们最初是发布的。
这是数组的一个示例。
nodes = [
{id: 'B', references: "A", date: "2020-12-30T11:00:01-01:00"},
{id: 'J', references: "F", date: "2020-12-30T11:00:06-01:00"},
{id: 'D', references: "A", date: "2020-12-30T11:00:07-01:00"},
{id: 'A', references: "", date: "2020-12-30T11:00:00-01:00"}, // initial post has no reference
{id: 'E', references: "C", date: "2020-12-30T11:00:03-01:00"},
{id: 'F', references: "E", date: "2020-12-30T11:00:04-01:00"},
{id: 'C', references: "A", date: "2020-12-30T11:00:02-01:00"},
{id: 'I', references: "G", date: "2020-12-30T11:00:09-01:00"},
{id: 'G', references: "A", date: "2020-12-30T11:00:08-01:00"},
{id: 'H', references: "G", date: "2020-12-30T11:00:09-02:00"},
{id: 'K', references: "F", date: "2020-12-30T11:00:05-01:00"},
];
目标是直观地打印有序的讨论树,如下所示:
A
_ B
_ C
_ _ E
_ _ _ F
_ _ _ _ K
_ _ _ _ J
_ D
_ G
_ _ I
_ _ H
我正在寻找 JavaScript 解决方案。
更新:
我发现,以下代码(数组中的所有条目都按天预先排序)将创建正确的树:
let arr = [
{id: 'A', references: "", date: "2020-12-30T11:00:00-01:00"},
{id: 'B', references: "A", date: "2020-12-30T11:00:01-01:00"},
{id: 'C', references: "A", date: "2020-12-30T11:00:02-01:00"},
{id: 'E', references: "C", date: "2020-12-30T11:00:03-01:00"},
{id: 'F', references: "E", date: "2020-12-30T11:00:04-01:00"},
{id: 'K', references: "F", date: "2020-12-30T11:00:05-01:00"},
{id: 'J', references: "F", date: "2020-12-30T11:00:06-01:00"},
{id: 'D', references: "A", date: "2020-12-30T11:00:07-01:00"},
{id: 'G', references: "A", date: "2020-12-30T11:00:08-01:00"},
{id: 'I', references: "G", date: "2020-12-30T11:00:09-01:00"},
{id: 'H', references: "G", date: "2020-12-30T11:00:09-02:00"},
];
function unflatten(arr) {
var tree = [],
mappedArr = {},
arrElem,
mappedElem;
// First map the nodes of the array to an object -> create a hash table.
for(var i = 0, len = arr.length; i < len; i++) {
arrElem = arr[i];
mappedArr[arrElem.id] = arrElem;
mappedArr[arrElem.id]['children'] = [];
}
for (var id in mappedArr) {
if (mappedArr.hasOwnProperty(id)) {
mappedElem = mappedArr[id];
// If the element is not at the root level, add it to its parent array of children.
if (mappedElem.references) {
mappedArr[mappedElem['references']]['children'].push(mappedElem);
}
// If the element is at the root level, add it to first level elements array.
else {
tree.push(mappedElem);
}
}
}
return tree;
}
var tree = unflatten(arr);
console.log(tree);
document.body.innerHTML = "<pre>" + (JSON.stringify(tree, null, " "))
结果:
[
{
"id": "A",
"references": "",
"date": "2020-12-30T11:00:00-01:00",
"children": [
{
"id": "B",
"references": "A",
"date": "2020-12-30T11:00:01-01:00",
"children": []
},
{
"id": "C",
"references": "A",
"date": "2020-12-30T11:00:02-01:00",
"children": [
{
"id": "E",
"references": "C",
"date": "2020-12-30T11:00:03-01:00",
"children": [
{
"id": "F",
"references": "E",
"date": "2020-12-30T11:00:04-01:00",
"children": [
{
"id": "K",
"references": "F",
"date": "2020-12-30T11:00:05-01:00",
"children": []
},
{
"id": "J",
"references": "F",
"date": "2020-12-30T11:00:06-01:00",
"children": []
}
]
}
]
}
]
},
{
"id": "D",
"references": "A",
"date": "2020-12-30T11:00:07-01:00",
"children": []
},
{
"id": "G",
"references": "A",
"date": "2020-12-30T11:00:08-01:00",
"children": [
{
"id": "I",
"references": "G",
"date": "2020-12-30T11:00:09-01:00",
"children": []
},
{
"id": "H",
"references": "G",
"date": "2020-12-30T11:00:09-02:00",
"children": []
}
]
}
]
}
]
https://jsfiddle.net/jarosciak/73xuk25q/3/
有更好的想法吗?