Javascript 如何从对象的平面数组创建树数组,然后为每个树节点编号';s级别,并在每个级别对节点进行排序?

Javascript 如何从对象的平面数组创建树数组,然后为每个树节点编号';s级别,并在每个级别对节点进行排序?,javascript,Javascript,注意:下面是解决方案 问题: 我需要代码将具有id和父值的平面对象数组转换为树。由于平面阵列是动态生成的,因此深度的级别数未知 此外,一旦项目在树中,我需要根据节点所在的树级别(根节点=级别0,根的直接子节点=级别1,子节点=级别2,等等)为节点分配一个级别属性值 最后,每个树级别的节点都应该按照id进行alpha排序。因此,应该对根id进行排序,然后是根的子节点,然后是子节点的子节点,等等 我发现一些解决方案至少满足了我的两个需求,但没有一个能够满足所有三个需求 解决方案: 为此: <!

注意:下面是解决方案

问题: 我需要代码将具有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>