user736893
user736893

Reputation:

How can I make this recursive?

Including the declaration of the 2d Array, how can I make the following recursive? I would like it to iterate until there are no "children()".

    self.buildRelationships = function () {
        relationships = [];
        relationships[0] = [];
        relationships[1] = [];
        relationships[2] = [];
        relationships[3] = [];
        relationships[0][0] = self.name();
        $.each(self.children(), function(i, child) {
            relationships[1][i] = child.name();
            $.each(child.children(), function (j, grandchild) {
                relationships[2][j] = grandchild.name();
                $.each(grandchild.children(), function (k, greatgrandchild) {
                    relationships[3][k] = greatgrandchild.name();
                })
            })
        })
    }

Visualization of objective

Given this data:

.children() returns immediate children only:

Bob.children() would return "James" and "Steve".

Me!.children() would return "Bob" and "Bill".

The accepted answer would create data that looked like this:

relationships[0] = "Me!" //this will always have a length of only 1
relationships[1] = "Bob", "Bill"
relationships[2] = "James", "Steve", "Fred"
relationships[3] = "Dale", "Owen", "Patrick"

Upvotes: 2

Views: 166

Answers (3)

violet313
violet313

Reputation: 1932

&for fun, here's a recursive jQuery plugin that can be invoked on a container that may or may not be a singleton "eve" creature (dependent upon whether or not the container element defines a name attribute) :

jsfiddle

$.fn.getImps=function(imps, i)
{
    if (!$.isArray(imps)) 
        throw new Error("oook: getImps requires an empty array!");
    i=(typeof i !== "undefined" ? i : 0);

    if (this.is("[name]"))
        (imps[i] || (imps[i]=[])).push(this.attr("name")) && i++;
    this.children().each(function(){ $(this).getImps(imps,i) });
} 


btw: since this is a breadth-first traversal, & typically implemented using non-recursive queue-based algos..:

jsfiddle

//expects a singleton container id 
var getImps=function(id)
{      
    var imps=[];     
    for(var o=$(id), a; (o=o.children("[name]")).length && imps.push(a=[]);)
        o.each(function() { a.push($(this).attr("name")) });
    return imps;
}

(= but only saying.. =)


Oook: um your creatures appear to be undergoing some kind of asexual reproduction ~are they maybe.. aphids?

Upvotes: 0

Mongus Pong
Mongus Pong

Reputation: 11477

self.buildRelationships = function () {
        relationships = [];
        relationships[0] = [];
        relationships[1] = [];
        relationships[2] = [];
        relationships[3] = [];
        relationships[0][0] = self.name();

        var recursive = function(level) {

            return function(i, child) {
               relationships[level] = relationships[level] || [];

               relationships[level].push(child.name());
               $.each(child.children(), recursive(level + 1));
            }
        }

        $.each(self.children(), recursive(1));
    }

Upvotes: 4

acjay
acjay

Reputation: 36521

Here's how I would approach it:

self.buildRelationships = function () {
    var relationships = [];
    addToLevel(self, 0);
    return relationships;

    function addToLevel(node, levelIndex) {
        $.each(node.children(), function (i, child) {
            if (relationships.length <= levelIndex) { relationships.push([]) }
            relationships[levelIndex].push(child.name()); 
            addToLevel(child, levelIndex + 1);
        });
    }
}

(I prefer using Underscore/Lodash for data processing, and reserving jQuery for DOM stuff. But jQuery only was assumed.)

Upvotes: 1

Related Questions