Like most programmers writing non-trivial applications, I’ve piled up a lot of utility functions over the years. Most of them are simple and effective. They are short and get their job done. You or someone you know has probably written these functions, but maybe not in AS3. So today I’m going to share a few utility functions for Objects in AS3.

Let’s begin with a pair of related functions: numProperties and hasProperties. Unlike Array and Vector, Object and its derivatives do not necessarily have a length field. Yet Object and Dictionary, in particular, are often used as collections and often a length is needed. Thankfully, this is a simple and relatively-quick task to complete in AS3. All that is required is that we loop over their properties keeping a sum. For hasProperties we do not need to count all of the properties as we can simply stop at the first one.

/**
*   Count the properties in an object
*   @param obj Object to count the properties of
*   @return The number of properties in the specified object. If the
*           specified object is null, this is 0.
*   @author Jackson Dunstan
*/
public static function numProperties(obj:Object): int
{
	var count:int = 0;
	for each (var prop:Object in obj)
	{
		count++;
	}
	return count;
}
 
/**
*   Check if an object has any properties
*   @param obj Object to check for properties
*   @return If the specified object has any properties. If the
*           specified object is null, this is false.
*   @author Jackson Dunstan
*/
public static function hasProperties(obj:Object): Boolean
{
	for each (var prop:Object in obj)
	{
		return true;
	}
	return false;
}

Next comes a utility function useful mainly for error checking: isUniformPropertyType. In languages like C++ and Java it is common to use templates or generics to specify the type of objects in a collection. AS3’s Object is also generic, but you can freely mix the types. Since you can’t specify the type and have the compiler and VM do that type-checking work for you, a utility function to inspect an Object is needed. This task is as simple as using the is operator on each property:

/**
*   Check if the properties of an object are all the same
*   @param obj Object whose properties should be checked
*   @param type Type to check the object's properties against
*   @return If all of the properties of the specified object are of the
*           specified type
*   @author Jackson Dunstan
*/
public static function isUniformPropertyType(obj:Object, type:Class): Boolean
{
	for each (var prop:Object in obj)
	{
		if (!(prop is type))
		{
			return false;
		}
	}
	return true;
}

Another common task that seems to be missing from the language and Flash API is the ability to make copies of Objects. Simply assigning one Object to another only makes two variables reference the same Object. Sometimes we would like to have our own copy, perhaps to save a state for later comparison or restoration. In general, this task might be problematic due to loops/cycles in the Object‘s properties or very deeply-nested Objects inside of Objects inside of Objects. This utility function deals with none of these issues and simply does a 1-level-deep copy. That is, only the Object‘s immediate properties are copied, but not the properties of the Object‘s properties. Also, it’s often nice to copy the properties into an existing object, so this is supported by a default parameter.

/**
*   Copy an object
*   @param obj Object to copy
*   @param into (optional) Object to copy into. If null, a new object
*                is created.
*   @return A one-level deep copy of the object or null if the argument
*           is null
*   @author Jackson Dunstan
*/
public static function copy(obj:Object, into:Object=null): Object
{
	if (into == null)
	{
		into = {};
	}
	if (obj != null)
	{
		for (var o:* in obj)
		{
			into[o] = obj[o];
		}
	}
	return into;
}

On the theme of functionality that would have been nice to have directly in the language or Flash API, it would have been nice to have a conversion from an Object to an Array. Here is one:

/**
*   Convert the object to an array. Note that the order of the array is
*   undefined.
*   @param obj Object to convert
*   @return An array with all of the properties of the given object or
*           null if the given object is null
*   @author Jackson Dunstan
*/
public static function toArray(obj:Object): Array
{
	if (obj == null)
	{
		return null;
	}
	else
	{
		var ret:Array = [];
		for each (var prop:Object in obj)
		{
			ret.push(prop);
		}
		return ret;
	}
}

Finally, here is a toString that does a 1-level-deep conversion. It features a customizable delimiter so you can adapt it for query strings, log output, HTML output, or whatever you’d like:

/**
*   Convert the object to a string of form: PROP: VAL&PROP: VAL where:
*     PROP is a property
*     VAL is its corresponding value
*     & is the specified optional delimiter
*   @param obj Object to convert
*   @param delimiter (optional) Delimiter of property/value pairs
*   @return An string of all property/value pairs delimited by the
*           given string or null if the input object or delimiter is
*           null.
*   @author Jackson Dunstan
*/
public static function toString(obj:Object=null, delimiter:String = "\n"): String
{
	if (obj == null || delimiter == null)
	{
		return "";
	}
	else
	{
		var ret:Array = [];
		for (var s:Object in obj)
		{
			ret.push(s + ": " + obj[s]);
		}
		return ret.join(delimiter);
	}
}

Like I said in the opening, none of these functions are particularly innovative, trickly, or unconventional. I’m positive that many people have written them many times before. These are just a collection of boilerplate utility functions for AS3. Hopefully it will save some of you some time.