Javascript 如何从对象的平面数组创建树数组,然后为每个树节点编号';s级别,并在每个级别对节点进行排序?
注意:下面是解决方案强> 问题: 我需要代码将具有id和父值的平面对象数组转换为树。由于平面阵列是动态生成的,因此深度的级别数未知 此外,一旦项目在树中,我需要根据节点所在的树级别(根节点=级别0,根的直接子节点=级别1,子节点=级别2,等等)为节点分配一个级别属性值 最后,每个树级别的节点都应该按照id进行alpha排序。因此,应该对根id进行排序,然后是根的子节点,然后是子节点的子节点,等等 我发现一些解决方案至少满足了我的两个需求,但没有一个能够满足所有三个需求 解决方案: 为此:Javascript 如何从对象的平面数组创建树数组,然后为每个树节点编号';s级别,并在每个级别对节点进行排序?,javascript,Javascript,注意:下面是解决方案 问题: 我需要代码将具有id和父值的平面对象数组转换为树。由于平面阵列是动态生成的,因此深度的级别数未知 此外,一旦项目在树中,我需要根据节点所在的树级别(根节点=级别0,根的直接子节点=级别1,子节点=级别2,等等)为节点分配一个级别属性值 最后,每个树级别的节点都应该按照id进行alpha排序。因此,应该对根id进行排序,然后是根的子节点,然后是子节点的子节点,等等 我发现一些解决方案至少满足了我的两个需求,但没有一个能够满足所有三个需求 解决方案: 为此: <!
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<ul>
<li>10
<ul>
<li>20
<ul>
<li>70</li>
<li>80</li>
</ul>
</li>
<li>30
<ul>
<li>40
<ul>
<li>90</li>
<li>95</li>
<li>100</li>
</ul>
</li>
<li>50
<ul>
<li>110</li>
</ul>
</li>
<li>60
<ul>
<li>120</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li>130
<ul>
<li>140
<ul>
<li>150</li>
<li>160
<ul>
<li>180</li>
<li>190
<ul>
<li>200</li>
</ul>
</li>
</ul>
</li>
<li>170</li>
</ul>
</li>
</ul>
</li>
</ul>
</body>
</html>
- 十,
- 二十
- 七十
- 八十
- 三十
- 四十
- 九十
- 九十五
- 一百
- 五十
- 110
- 六十
- 120
- 130
- 140
- 一百五十
- 一百六十
- 180
- 190
- 二百
- 170
如果我的小提琴不见了,下面是我的完整解决方案:
<html>
<script>
window.onload = function () {
// STEP 1: Get a flat array of objects.
/* A flat (1 dimensional) array, which can later be turned into a tree, since each array item has an id and parent property. */
var x = [
{id: 10, parent: 0, children: []}, // 2 immediate children, root node
{id: 20, parent: 10, children: []}, // 2 immediate children
{id: 30, parent: 10, children: []}, // 3 immediate children
{id: 40, parent: 30, children: []}, // 3 immediate children
{id: 50, parent: 30, children: []}, // 1 immediate children
{id: 60, parent: 30, children: []}, // 1 immediate children
{id: 70, parent: 20, children: []}, // 0 immediate children
{id: 80, parent: 20, children: []}, // 0 immediate children
{id: 90, parent: 40, children: []}, // 0 immediate children
{id: 100, parent: 40, children: []}, // 0 immediate children
{id: 95, parent: 40, children: []}, // 0 immediate children
{id: 110, parent: 50, children: []}, // 0 immediate children
{id: 120, parent: 60, children: []}, // 0 immediate children
{id: 130, parent: 0, children: []}, // 1 immediate children, root node
{id: 140, parent: 130, children: []}, // 3 immediate children
{id: 150, parent: 140, children: []}, // 0 immediate children
{id: 160, parent: 140, children: []}, // 2 immediate children
{id: 170, parent: 140, children: []}, // 0 immediate children
{id: 180, parent: 160, children: []}, // 0 immediate children
{id: 190, parent: 160, children: []}, // 1 immediate children
{id: 200, parent: 190, children: []} // 0 immediate children; 5 levels deep (level = 4, since start level is 0)
];
// STEP 2: Turn the flat array into a tree (hierarchical) array.
function tierData (arr) {
/*
Params:
@arr = flat array. Each array item is an object containing id, parent, and children properties.
Description:
Takes a flat array and turns into into a tree (hierarchical) array.
*/
for (var i = 0; i < arr.length; i++) {
arr.forEach(function (n) {
if (n.parent === arr[i].id) {
arr[i].children.push(n);
}
});
}
return arr.filter(function (n) { return n.parent === 0 }); // Only return root nodes and their children, children's children, etc.
}
var td = tierData(x);
//console.log(td);
// STEP 3: Assign a "level" property to each tree level. Numeric sort tree items for each level in the tree.
function treeSortAndLevel (treeArr,flatArr,flatIndex) {
/*
Params:
@treeArr = A tree (hierarchical) array, created from a flat array using the tierData fn.
@flatArr = A flat array on which @treeArr is based.
@flatIndex = DON'T PASS AN ARG. This is assigned a value by subsequent recursive fn calls.
Description:
Returns a tree which is numeric sorted at each level and each tree node is assigned a level property value, starting with root node(s) level = 0.
*/
// If not provided (ie the fn's first call), create an indexer for the flat array.
if (flatIndex === undefined) {
var flatIndex = {};
for (var i = 0; i < flatArr.length; i++) {
flatIndex[flatArr[i].id] = flatArr[i];
}
}
for (var i = 0; i < treeArr.length; i++) {
// Numeric sort the current treeArr tier (ie array) by id.
treeArr.sort(function (a, b) { return a.id - b.id; });
// Determine and set the treeArr item's level.
var parentId = treeArr[i].parent;
var level = 0;
while (parentId !== 0) {
level++;
var ancestor;
ancestor = flatIndex[parentId];
parentId = ancestor.parent;
}
treeArr[i].level = level;
treeSortAndLevel(treeArr[i].children,flatArr,flatIndex);
}
return treeArr;
}
var sortedAndLeveldTree = treeSortAndLevel(td,x);
console.log(sortedAndLeveldTree);
// STEP 4: Append a multi-tiered unordered list to the DOM for the sorted and level numbered tree.
function printTree (treeArr) {
/*
Params:
@treeArr = A tree (hierarchical) array, created from a flat array using the tierData fn.
Description:
Prints a tree to the console.
*/
for (var i = 0; i < treeArr.length; i++) {
var indent = '';
var level = treeArr[i].level;
while (level > 0) {
indent += ' -- ';
level--;
}
console.log(indent + treeArr[i].id);
printTree(treeArr[i].children);
}
}
function createTreeDOM (treeArr, ul) {
/*
Params:
@treeArr = A tree (hierarchical) array, created from a flat array using the tierData fn.
@ul = DON'T PASS AN ARG. This is assigned a value by subsequent recursive fn calls.
Description:
Returns an unordered list tree (DOM element).
*/
if (ul === undefined) {
ul = document.createElement('ul');
}
for (var i = 0; i < treeArr.length; i++) {
var li = document.createElement('li');
var tx = document.createTextNode(treeArr[i].id);
li.appendChild(tx);
if (treeArr[i].children.length > 0) {
var subUL = document.createElement('ul');
li.appendChild(subUL);
createTreeDOM(treeArr[i].children, subUL);
}
ul.appendChild(li);
}
return ul;
}
// Alternatively, print the sorted and level numbered tree to the console in a tree-like style using the printTree fn:
//printTree(sortedAndLeveldTree);
var p = document.createElement('p');
p.innerHTML = 'The below tree was dynamically created from a flat array of objects using JS. Tree items (the objects, not the DOM elements) are assigned a level property, starting with 0 for root items. Tree items are sorted by their id at each tier (tree level).';
document.body.appendChild(p);
var treeDOM = createTreeDOM(sortedAndLeveldTree);
document.body.appendChild(treeDOM);
}
</script>
</html>
window.onload=函数(){
//步骤1:获取对象的平面阵列。
/*平面(一维)数组,由于每个数组项都有一个id和父属性,因此以后可以将其转换为树*/
变量x=[
{id:10,父节点:0,子节点:[]},//2个直接子节点,根节点
{id:20,父项:10,子项:[]},//2个直接子项
{id:30,父项:10,子项:[]},//3个直接子项
{id:40,父对象:30,子对象:[]},//3个直接子对象
{id:50,父对象:30,子对象:[]},//1个直接子对象
{id:60,父项:30,子项:[]},//1个直接子项
{id:70,父项:20,子项:[]},//0个直接子项
{id:80,父项:20,子项:[]},//0个直接子项
{id:90,父项:40,子项:[]},//0个直接子项
{id:100,父项:40,子项:[]},//0个直接子项
{id:95,父项:40,子项:[]},//0个直接子项
{id:110,父项:50,子项:[]},//0个直接子项
{id:120,父项:60,子项:[]},//0个直接子项
{id:130,父节点:0,子节点:[]},//1直接子节点,根节点
{id:140,父项:130,子项:[]},//3个直接子项
{id:150,父项:140,子项:[]},//0个直接子项
{id:160,父项:140,子项:[]},//2个直接子项
{id:170,父项:140,子项:[]},//0个直接子项
{id:180,父项:160,子项:[]},//0个直接子项
{id:190,父项:160,子项:[]},//1个直接子项
{id:200,父级:190,子级:[]}//0个直接子级;5级深(级别=4,因为起始级别为0)
];
//步骤2:将平面阵列转换为树(层次)阵列。
功能层次数据(arr){
/*
参数:
@arr=平面数组。每个数组项都是一个包含id、父属性和子属性的对象。
说明:
获取平面数组并转换为树(层次)数组。
*/
对于(变量i=0;i<html>
<script>
window.onload = function () {
// STEP 1: Get a flat array of objects.
/* A flat (1 dimensional) array, which can later be turned into a tree, since each array item has an id and parent property. */
var x = [
{id: 10, parent: 0, children: []}, // 2 immediate children, root node
{id: 20, parent: 10, children: []}, // 2 immediate children
{id: 30, parent: 10, children: []}, // 3 immediate children
{id: 40, parent: 30, children: []}, // 3 immediate children
{id: 50, parent: 30, children: []}, // 1 immediate children
{id: 60, parent: 30, children: []}, // 1 immediate children
{id: 70, parent: 20, children: []}, // 0 immediate children
{id: 80, parent: 20, children: []}, // 0 immediate children
{id: 90, parent: 40, children: []}, // 0 immediate children
{id: 100, parent: 40, children: []}, // 0 immediate children
{id: 95, parent: 40, children: []}, // 0 immediate children
{id: 110, parent: 50, children: []}, // 0 immediate children
{id: 120, parent: 60, children: []}, // 0 immediate children
{id: 130, parent: 0, children: []}, // 1 immediate children, root node
{id: 140, parent: 130, children: []}, // 3 immediate children
{id: 150, parent: 140, children: []}, // 0 immediate children
{id: 160, parent: 140, children: []}, // 2 immediate children
{id: 170, parent: 140, children: []}, // 0 immediate children
{id: 180, parent: 160, children: []}, // 0 immediate children
{id: 190, parent: 160, children: []}, // 1 immediate children
{id: 200, parent: 190, children: []} // 0 immediate children; 5 levels deep (level = 4, since start level is 0)
];
// STEP 2: Turn the flat array into a tree (hierarchical) array.
function tierData (arr) {
/*
Params:
@arr = flat array. Each array item is an object containing id, parent, and children properties.
Description:
Takes a flat array and turns into into a tree (hierarchical) array.
*/
for (var i = 0; i < arr.length; i++) {
arr.forEach(function (n) {
if (n.parent === arr[i].id) {
arr[i].children.push(n);
}
});
}
return arr.filter(function (n) { return n.parent === 0 }); // Only return root nodes and their children, children's children, etc.
}
var td = tierData(x);
//console.log(td);
// STEP 3: Assign a "level" property to each tree level. Numeric sort tree items for each level in the tree.
function treeSortAndLevel (treeArr,flatArr,flatIndex) {
/*
Params:
@treeArr = A tree (hierarchical) array, created from a flat array using the tierData fn.
@flatArr = A flat array on which @treeArr is based.
@flatIndex = DON'T PASS AN ARG. This is assigned a value by subsequent recursive fn calls.
Description:
Returns a tree which is numeric sorted at each level and each tree node is assigned a level property value, starting with root node(s) level = 0.
*/
// If not provided (ie the fn's first call), create an indexer for the flat array.
if (flatIndex === undefined) {
var flatIndex = {};
for (var i = 0; i < flatArr.length; i++) {
flatIndex[flatArr[i].id] = flatArr[i];
}
}
for (var i = 0; i < treeArr.length; i++) {
// Numeric sort the current treeArr tier (ie array) by id.
treeArr.sort(function (a, b) { return a.id - b.id; });
// Determine and set the treeArr item's level.
var parentId = treeArr[i].parent;
var level = 0;
while (parentId !== 0) {
level++;
var ancestor;
ancestor = flatIndex[parentId];
parentId = ancestor.parent;
}
treeArr[i].level = level;
treeSortAndLevel(treeArr[i].children,flatArr,flatIndex);
}
return treeArr;
}
var sortedAndLeveldTree = treeSortAndLevel(td,x);
console.log(sortedAndLeveldTree);
// STEP 4: Append a multi-tiered unordered list to the DOM for the sorted and level numbered tree.
function printTree (treeArr) {
/*
Params:
@treeArr = A tree (hierarchical) array, created from a flat array using the tierData fn.
Description:
Prints a tree to the console.
*/
for (var i = 0; i < treeArr.length; i++) {
var indent = '';
var level = treeArr[i].level;
while (level > 0) {
indent += ' -- ';
level--;
}
console.log(indent + treeArr[i].id);
printTree(treeArr[i].children);
}
}
function createTreeDOM (treeArr, ul) {
/*
Params:
@treeArr = A tree (hierarchical) array, created from a flat array using the tierData fn.
@ul = DON'T PASS AN ARG. This is assigned a value by subsequent recursive fn calls.
Description:
Returns an unordered list tree (DOM element).
*/
if (ul === undefined) {
ul = document.createElement('ul');
}
for (var i = 0; i < treeArr.length; i++) {
var li = document.createElement('li');
var tx = document.createTextNode(treeArr[i].id);
li.appendChild(tx);
if (treeArr[i].children.length > 0) {
var subUL = document.createElement('ul');
li.appendChild(subUL);
createTreeDOM(treeArr[i].children, subUL);
}
ul.appendChild(li);
}
return ul;
}
// Alternatively, print the sorted and level numbered tree to the console in a tree-like style using the printTree fn:
//printTree(sortedAndLeveldTree);
var p = document.createElement('p');
p.innerHTML = 'The below tree was dynamically created from a flat array of objects using JS. Tree items (the objects, not the DOM elements) are assigned a level property, starting with 0 for root items. Tree items are sorted by their id at each tier (tree level).';
document.body.appendChild(p);
var treeDOM = createTreeDOM(sortedAndLeveldTree);
document.body.appendChild(treeDOM);
}
</script>
</html>