Javascript transforms the relationship between elements in an array from a parent-child structure to a tree structure.

Aim: To transform the relationship between elements in an array into a tree structure.

Thoughts and steps

  1. Traverse elements of an array into a map, id as key
  2. Then loop through the array to get each element, find the parent node of the element, and join the child tree of the node if there is a parent node. Without a parent node, the node is the root node. (The way to find the parent node is to find it in the map through the element pid).

Specific Code Implementation Note: The code contains some ES6 syntax.
Create a new Collections.js file

// Collection Tool Class

function required(item, message = '') {
    if (!item) {
        throw new Error(message + 'is required');
    }
}

const Collections = {

    /**
     *
     * @param sourceArray To convert the original data of the tree structure
     * @param rootNodeIdentifier Root node identifier
     * @param pIdentifier Parent Node Identifier
     * @param cIdentifier Direct Point Identifier
     * @return {Error|IterableIterator<any>} Normally returns an array of tree structures
     */
    turnTree(sourceArray, rootNodeIdentifier, pIdentifier, cIdentifier) {
        required(sourceArray, 'The array to be converted cannot be empty');
        required(pIdentifier, 'Parent node identifier cannot be null');
        required(cIdentifier, 'The current node identifier cannot be null');

        let sourceArrayCopy = [...sourceArray];
        if (pIdentifier === cIdentifier) {
            return new Error('The current node identifier cannot be the same as the parent node identifier');
        }

        // Traversal array added to map
        let sourceMap = new Map();
        sourceArrayCopy.forEach(item => {
            item.children = null;
            sourceMap.set(item[cIdentifier], item)
        });

        // Tree node set
        let tree = new Map();
        while (sourceArrayCopy.length > 0) {
            sourceArrayCopy.forEach((item, index) => {
                if (rootNodeIdentifier === item[pIdentifier]) {
                    tree.set(item[cIdentifier], item);
                    sourceArrayCopy.splice(index, 1)
                }else {
                    const node = sourceMap.get(item[pIdentifier]);
                    if (node.children == null) {
                        node.children = [];
                    }
                    node.children.push(item);
                    sourceArrayCopy.splice(index, 1)
                }
            });
        }
        sourceMap = null;
        sourceArrayCopy = null;
        return [...tree.values()];
    }
};

export default Collections;

test case

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

<script type="module">

    import Collections from './Collections.js'


    let array = [
        {
            pid: null,
            id: 1,
            name: 'Blue community',
        },
        {
            pid: 1,
            id: 11,
            name: 'A Tung',
        },
        {
            pid: 11,
            id: 111,
            name: '7 floor',
        },
        {
            pid: null,
            id: 2,
            name: 'Green District',
        },
        {
            pid: 2,
            id: 20,
            name: 'A Tung',
        },
        {
            pid: 20,
            id: 200,
            name: '20 floor',
        }
        ,
        {
            pid: 200,
            id: 201,
            name: '705 Room',
        }
    ];


    let turnTree = Collections.turnTree(array,null,'pid','id');

    console.log(array);
    console.log(turnTree)
</script>
</body>
</html>

Tip: If the browser now runs the import command directly, it needs to write as follows:

// type="module" is the key
<script type="module">
import Collections from './Collections.js'


Posted by azfar siddiqui on Thu, 18 Apr 2019 20:24:35 -0700