[code] getFirstValue and addObjectPath

Here are a couple of simple but very useful code snippets that you may find handy. They are part of the library of utility functions that support FlashOS2 – I was reminded of them as I needed them for a project I’m currently working on. Apologies in advance for the page stretching all over the place.

getFirstValue
This function simply returns the first non-null value passed to it. This is really useful in situations where you have a value hierarchy, and need to get the first value that actually exists. For example, you may have a color hierarchy for skinning, instead of using a bunch of if statements to get the first existing value, you could do the following:

color1 = null;
// we won't define a color2
color3 = null;
color4 = "FF0000";
// or a color5
var myColor = getFirstValue(color1,color2,color3,color4,color5,"000000");
trace(myColor); // traces 'FF0000" (color4)

The function is simple:

function getFirstValue() {
var l = arguments.length;
for (var i=0;i<l;i++) {
if (arguments[i] != null) { return arguments[i]; }
}
return null;
}

addObjectPath
Sometimes you need to build complicated object hierarchies, but don’t want to use a class to do it. Say you were dynamically creating an animal taxonomy, and wanted to insert wolf in canine in mammal in animal in the taxonomy object, but you don’t know which of those objects already exists, and you certainly don’t want to overwrite the ones that do. Rather than using if statements, you could use addObjectPath as follows:

taxonomyObj = {};
// add the taxonomyObj.animal.mammal.canine object:
canineObj = addObjectPath(taxonomyObj,"animal.mammal.canine");
// create a wolf attibute in the canine object:
canineObj.wolf = "Wicked Wolf";
// let's also add a chimpanzee in primates:
primateObj = addObjectPath(taxonomyObj,"animal.mammal.primate");
primateObj.chimpanzee = "Bob";
trace(taxonomyObj.animal.mammal.canine.wolf); // traces 'Wicked Wolf'
trace(taxonomyObj.animal.mammal.primate.chimpanzee); // traces 'Bob'
// notice that adding primate did not delete the canine object.

This is a recursive function (ie. it calls itself), so picking it apart can be a little tricky. Basically, it takes two parameters: the first parameter is the object to start building the path from, the second is a string containing the desired object path in dot syntax (the third parameter, index, is used internally by the function). The function will not destroy any existing objects, and will return null if it encounters an existing variable in the path that is not an object (if taxonomyObj.animal.mammal was already defined as a String in the example above, for instance).

Here’s the function:

function addObjectPath(p_object,p_path,p_index) {
if (typeof(p_path) == "string") { p_path = p_path.split("."); }
else if (p_path == null) { return p_object; }
p_index = Number(p_index);
if (p_object[p_path[p_index]] == null) { p_object[p_path[p_index]] = {}; }
else if (typeof(p_object) != "object" || p_object instanceof Array) { return null; }
if (p_index == p_path.length-1) { return p_object[p_path[p_index]]; }
else { return addObjectPath(p_object[p_path[p_index]],p_path,p_index+1); }
}

Hope these are helpful for someone, they’ve been quite useful for many of my projects.

Grant Skinner

The "g" in gskinner. Also the "skinner".

@gskinner