| Register
Friday, May 09, 2008   

Recursive Functions and TypeOf

Created By  Benjamin Mace, at  8/10/2004 - 16 comments.

Click to view this author's website.

It's a simple concept. Allow a function to call itself with a new parameter until a condition is met. A tried and true method of solving smaller problems until a larger one is solved. One of the simplest concepts in programming is rarely taken advantage of in Flash, but couldn't possibly fit better within Flash itself seeing how all our objects are like tree structures.

In mathematics and programming, recursion is when a function (or procedure) calls itself. In the following example we will increment a number with each pass until a condition is met. Never forget to place a condition within the recursion to avoid an infinite loop.

myCounter = function (i) {
	// make sure we can leave the loop
	if (i<=100)
	{
		trace(i)
		i++
		myCounter(i)
	}
}
myCounter(0);

By passing a parameter to the function we can the dig deeper into a problem with each pass. Take for example XML. A simple recursive function call can allow you to pass in a node within the tree and walk through each subsequent level of the node. Try this code in Flash with any XML doc or RSS feed online. (Note that I'm using 'for.. in' as a conditional here and in the remaining examples to end the recursion.)

traceNodes = function(theNode)
{
	for(child in theNode.childNodes)
	{
		var currentNode = theNode.childNodes[child];
		if(currentNode.nodeName != null)
		{			
			trace(currentNode.nodeName);
			traceNodes(currentNode);	
		}
	}
}

loadrssXML = function() {
	rssXML = new XML();
	rssXML.ignoreWhite = true;
	rssXML.onLoad = parseXML;
	rssXML.load("http://www.actionscript.com/asc_news.xml");
}

parseXML = function ()
{
	traceNodes(rssXML)
}

loadrssXML();

You can walk through almost any object in Flash. Take a multidimensional array for example. With a recursive function, we can walk through each array within the parent array and get, change or delete values etc. All we have to do is pass the new child back to the function and walk through it. Take this function for example. It will walk through everything in a given object/timeline:

traceEverything = function (obj)
{
	for (item in obj) 
	{
		trace("Found: " + item + ", which is a " + typeof(obj[item]));
		traceEverything(obj[item]);
	}
}

traceEverything(this);

While recursion on its own is an enormously powerful practice in programming and within Flash as we have seen here, we have access to a lot of information within our objects. Thankfully Flash has given us the expression 'typeOf'. In the ActionScript Dictionary, typeOf states:

'The typeof operator causes the Flash interpreter to evaluate expression; the result is a string specifying whether the expression is a string, movie clip, object, function, number, or Boolean value.'

By evaluating the object that is returned, we can setup our recursion to only give us back needed information. For example, if we wanted to loop through everything on a timeline, but only do something with the strings found we could check for 'string' and then do something with each string.

Something I have used recently is a recursive function that walks through the movieclip object. By passing in an object such as 'this' from the main timeline, we can look though and find each nested sub-sequential clip within that level. Take for example the follow recursive function in combination with typeOf:

traceClips = function (timeline)
{
	for (clipName in timeline) 
	{
		if (typeof (timeline[clipName]) == "movieclip") 
		{	
			trace(timeline);
			traceClips(timeline[clipName]);
		}
	}
}

traceClips(this);

Something as simple as this opens up many possibilities for a Flash developers. Imagine a situation where dynamic clips are attached or created frequently like browser windows on your pc. You could do a recursive function to loop through clips within clips to call a minimize function on all the windows. The sky is the limit here. With a bit of creativity and a few built in expressions, you can automate many processes within your movies and save lots of time.

Need Professional Help For Your ActionScript Project?
ActionScript.com Consulting Services provide top quality professional ActionScript consulting to businesses around the globe. If you have a professional project in need to world-class talent, tell us about your project by requesting a quote today.

Reader Comments

  1. Dave  Replied:
    ( 8/14/2004 At 7:20 AM)

    I noticed the sample code you gave shows the actionscript.com rss feed information in reverse. How would one go about "putting the top information on top" so to speak? Woud you put each child's data in an array and use the reverse() method? Or is there a better way.

  2. PiXELWiT  Replied:
    ( 8/30/2004 At 11:37 AM)

    The technique you use to find child clips is fine as long as you don't store references to non-child clips within other clips. For example, try running the following code:

  3. tutash  Replied:
    ( 11/4/2004 At 3:25 AM)

    I've used recursion to create an interface generated from XML. It is totally dynamic and flexible. I don't think there would be any other pratical way to do this without using recursion. Its nice to see someone using these methods in Flash besides myself.

  4. netfire  Replied:
    ( 11/5/2004 At 9:38 PM)

    Based on the idea of using Recursion to display an XML document, I've created one that show the levels or depth of the XML document, but I would also like to show the attributes of all the parent tags of the document. the code curNode.attributes should return an array, but returns undefined. To get anything from this line of code you have to specify the attribute that you want to read using this syntax curNode.attributes.attributeName. Is there any way to print out all the attributes of any XML tag?
    See my code below:
    XMLFile = "course_final.xml";
    courseInfo = new XML();
    courseInfo.ignoreWhite = true;
    courseInfo.load(XMLFile);
    courseInfo.onLoad = startReadingXML;
    depth = 0;
    function startReadingXML() {
    readXML(courseInfo.firstChild);
    }
    function readXML(curNode) {
    do {
    if (curNode.hasChildNodes()) {
    trace(makeTabs() + curNode.nodeName + " - " + curNode.attributes);
    depth++;
    readXML(curNode.firstChild);
    depth--;
    }
    else {
    trace (makeTabs() + curNode);
    }
    curNode = curNode.nextSibling;
    }
    while (curNode.nextSibling!=null);
    }
    function makeTabs() {
    tabstr = "";
    for (i=0; itabstr+="\\t";
    }
    return tabstr;
    }

  5. Max  Replied:
    ( 12/15/2004 At 4:55 AM)

    Recursive functions are tricky.
    You can spend days on finding a bug in them.

  6. joe  Replied:
    ( 12/15/2004 At 8:46 AM)

    recursing is not good when you want big things. takes up more time.

  7. AndreCassal  Replied:
    ( 2/4/2005 At 8:02 AM)

    Inside of the funcion you can use arguments.callee instead of same function name
    function __rec__(n){
    /*
    code
    */
    arguments.callee(n[index])
    }

  8. amin  Replied:
    ( 5/24/2005 At 5:01 PM)

    hi i need some example of recursive function in mathematic thanks alot

  9. vishnu  Replied:
    ( 7/12/2005 At 9:43 AM)

    hi guys,
    variables should be local to that function and what's the use of recursion if a called function alters the variable of the calling function.(ie..both are same functions)
    ------------------------------------
    function sample(sa){
    var i=0;
    i=sa;
    trace(i);
    if(i==3){
    return;
    }else{
    i++;
    sample(i);
    }
    }
    sample(0);
    NOTE:Actual recursion is expected to run this sample program for 3!(3 factorial times==> 6 times) and flash does this only 3 times b'cos (var i) is considered global inside all its child functions...hope u get my point
    -----------------------------------
    if any one could give me an example of a variable truely local to that functional block, i would really benifit from that ..
    please help me.

  10. m@  Replied:
    ( 8/1/2005 At 9:32 PM)

    Hello Netfire / All,
    your xml xample is realy interesting .
    I just wonder why it leaves out certain Nodes.
    (for example i used it with a nested XML file Structure and
    there are 4 Nodes in 1 Nest it reads out just 3 sometimes just 2)
    i tested it now with different changes but with no success until now
    i think there is something about this nextSibling thingy
    thnx in advantage
    m@

  11. vishnu  Replied:
    ( 8/4/2005 At 3:36 PM)

    hi,
    i have a small problem with xml.
    i have a sample below...








    what am i supposed to do if i need to hide or mask the first child node eg:
    please help me out,
    thanks..

  12. Andr  Replied:
    ( 8/5/2005 At 7:23 AM)

    What about the 256-level recursion limit in Flash ?

  13. mLearst  Replied:
    ( 8/18/2005 At 6:02 PM)

    Andr you will run into that problem if you're getting to that limit. What I suggest is using a setInterval along with recursion. This way you're calling the function in intervals and not running into the 256-level recursion limit.

  14. Brian  Replied:
    ( 8/23/2005 At 5:21 PM)

    A general rule of thumb is to use iteration for large scale repeated operations, and reserve recursion for operations with less "loops" to go through.
    The reason for this is that recursion, while powerful, is more resource-intensive than iteration. Every time a function is called, it has to allocate memory for itself. So as the stack gets higher, memory starts to get used up pretty fast. I think this is the reason for Flash's 256 levels of recursion limit.

  15. vishnu  Replied:
    ( 9/13/2005 At 1:22 AM)

    how do i get all displayed node details of tree so that,once i refresh tree i can collapse tree to previous state

  16. Rosario Azzarello  Replied:
    ( 11/4/2007 At 7:50 AM)

    Hi guys :o)

    I've tried the codes, but I don't understand how can I use it... :(

    Can someone upload a zip file with a example, pls?....

    THX----

Login to post your comments. If you do not have an account with us please Register.
Copyright 2005 by ActionScript, Inc.   |  Privacy Statement  |  Terms Of Use  |  ActionScript Client Extranet