Treeify and Flatten

converting between arrays and trees

by Josh McDaniel

HTML

<script src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.2.14/angular.js"></script>
<div ng-controller="myController">
    See console for output!
</div>

JavaScript

/* APP MODULE */
angular.module("app", []);

angular.module("app").controller("myController", function ($scope) {
    var list = [{
        id: 1,
        title: "home",
        parent: null,
        level: 1
    }, {
        id: 2,
        title: "about",
        parent: null,
        level: 1
    }, {
        id: 3,
        title: "team",
        parent: 2,
        level: 2
    }, {
        id: 4,
        title: "company",
        parent: 2,
        level: 2
    }];
    
    var treeWithIncorrectParents = {
        children: [{
            id: 1,
            title: "home",
            parent: null,
            children: []
        }, {
            id: 2,
            title: "about",
            parent: 17,
            children: [{
                id: 3,
                title: "team",
                parent: null,
                children: []
            }, {
                id: 4,
                title: "company",
                parent: null,
                children: []
            }]
        }]
    };
    
    //excellent algorithm found here: http://stackoverflow.com/a/22367819/3123195
    function treeify(list, idAttr, parentAttr, childrenAttr) {
        if (!idAttr) idAttr = 'id';
        if (!parentAttr) parentAttr = 'parent';
        if (!childrenAttr) childrenAttr = 'children';

        var lookup = {};
        var result = {};
        result[childrenAttr] = [];

        list.forEach(function(obj) {
            lookup[obj[idAttr]] = obj;
            obj[childrenAttr] = [];
        });

        list.forEach(function(obj) {
            if (obj[parentAttr] != null) {
                lookup[obj[parentAttr]][childrenAttr].push(obj);
            } else {
                result[childrenAttr].push(obj);
            }
        });

        return result;
    };
    
    //my own creation
    function flatten(treeObj, idAttr, parentAttr, childrenAttr, levelAttr) {
        if (!idAttr) idAttr = 'id';
        if (!parentAttr) parentAttr = 'parent';
        if...