JSFiddle - React, Tailwind, and code Playground

by CrossEye

HTML

<pre><code id="output"></code></pre>

JavaScript

var makeTree = (function() {
    var isArray = function(obj) {
        return Object.prototype.toString.call(obj) == "[object Array]"; 
    };
    var clone = function(obj) {return JSON.parse(JSON.stringify(obj));};
    var buildTree = function(catalog, structure, start) {
        return (structure[start] || []).map(function(id, index) {
            var record = catalog[id];
            var keys = structure[start][index];
            var children = isArray(keys) ? keys.map(function(key) {
                return buildTree(catalog, structure, key);
            }) : buildTree(catalog, structure, keys);
            if (children.length) {
                record.children = children;
            }
            return record;
        })
    };
    return function(flat) {
        var catalog = flat.reduce(function(catalog, record) {
            catalog[record.id] = clone(record);
            delete(catalog[record.id].parent);
            return catalog;
        }, {});
        var structure = flat.reduce(function(tree, record) {
            (tree[record.parent] = tree[record.parent] || []).push(record.id);
            return tree;
        }, {});
        return buildTree(catalog, structure, 0); // this might be oversimplified.
    }
}());


var flat = [
    { id: 1, name: "Business", parent: 0 },
    { id: 2, name: "Management", parent: 1 },
    { id: 3, name: "Leadership", parent: 2 },
    { id: 4, name: "Finance", parent: 1 },
    { id: 5, name: "Fiction", parent: 0 },
    { id: 6, name: "Accounting", parent: 1 },
    { id: 7, name: "Project Management", parent: 2  }
];

// Just for displaying output
var log = (function() {
    var o = document.getElementById("output");
    return function() {o.innerHTML += "\n" + [].join.call(arguments, ", ");}
}());

log(JSON.stringify(makeTree(flat), null, 4));