Simple Trees

JavaScript

function Node(contents, children) {
    return {
        contents: contents || {},
        children: children || []
    };
}

var tree =
    Node(1, [
        Node(2, [
            Node(5),
            Node(6)
        ]),
        Node(3),
        Node(4, [
            Node(7)
        ])
    ]);

console.log(tree);



function TreeTraversal(tree) {

    var _limit = 0;

    var _index = 0;

    var _self = {
        limit: limit,
        each:  each,
        map:   map,
        tree:  tree
    };

    return _self;

    //---

    // reads / writes the maximum number of nodes to visit
    // 0 means unlimited, i.e. visit all nodes
    function limit(at) {
        if (typeof at == 'undefined') {
            return _limit;
        }
        _limit = Math.abs(at) || 0;
        return _self;
    }

    // true if the limit is still to be reached
    function before_limit() {
        return _limit == 0 || _index < _limit;
    }

    // visits each node in a pre-order depth-first traversal
    // the callback gets 'this' set to the current node 
    // the callback gets an argument set to the zero-based index of the node during the traversal
    // the callback can return false to immediately stop the traversal
    function each(callback) {
        var once_more = true;
        _index = 0;
        var remaining_nodes = [tree];

        while( once_more && before_limit() && remaining_nodes.length ) {
            var current_node = remaining_nodes.shift();
            remaining_nodes = current_node.children.concat(remaining_nodes);

            once_more = callback.call(current_node, _index++) !== false;
        }

        return _self;
    }

    // visits each node in a pre-order depth-first traversal
    // the callback gets 'this' set to the current node 
    // the callback gets an argument set to the zero-based index of the node during the traversal
    // the callback gets an argument set to the contents of the current node
    // the callback must return a...