It’s been a while since I’ve posted a utility function, but today I’m breaking the streak and posting a couple of related functions I frequently find useful in debugging: joinN and joinNLabeled. These functions are like Array.join and Vector.join, but they group elements of the array to make the resulting string much easier to read.

If you call Array.join or Vector.join on a big set of data for debugging purposes, you often end up with an incomprehensible mess. It’s often the case that the elements of the list are grouped in some way, such as groups of X and Y and Z coordinates or widths and heights. In that case, consider what you normally get:

trace([1,2,3,4,5,6,7,8,9,10].join(","));
// output: 1,2,3,4,5,6,7,8,9,10

That’s hard to read. Now let’s look at what you get with joinN:

joinN(" ... ", ",", 2, [1,2,3,4,5,6,7,8,9,10]);
// output: 1,2 ... 3,4 ... 5,6 ... 7,8 ... 9,10

See how much easier it is to read the groupings? Now let’s see how it gets even better with joinNLabeled:

joinNLabeled(" ... ", ",", ":", ["X","Y"], [1,2,3,4,5,6,7,8,9,10]);
// output: X:1,Y:2 ... X:3,Y:4 ... X:5,Y:6 ... X:7,Y:8 ... X:9,Y:10

These are simple groupings of two elements, but how does it look with something more complex like the data in a vertex buffer for Stage3D?

joinNLabeled("\n", ", ", ": ", ["X","Y","Z","U","V"], [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15]);
// output:
X:1, Y:2, Z:3, U:4, V:5
X:6, Y:7, Z:8, U:9, V:10
X:11, Y:12, Z:13, U:14, V:15

Compare that to plain old join:

[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15].join(", ");
// output: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15

I know which version I prefer! Here’s the source code:

/**
*   Join the elements of an Array or Vector into a String
*   @param sep Separator between groups of N elements
*   @param subSep Separator between elements within a group
*   @param n Number of elements per group
*   @param list Array or Vector to join
*   @return The elements of the given Array or Vector grouped as a String
*   @author Jackson Dunstan (http://JacksonDunstan.com)
*   @license MIT
*/
public static function joinN(sep:String, subSep:String, n:uint, list:*): String
{
	var joined:String = "";
	for (var i:uint, len:uint = list.length; i < len;)
	{
		if (i)
		{
			joined += sep;
		}
		for (var j:uint = 0; j < n && i < len; ++j, ++i)
		{
			if (j)
			{
				joined += subSep;
			}
			joined += list[i];
		}
	}
	return joined;
}
 
/**
*   Join the elements of an Array or Vector into a String and prefix each element with a
*   label
*   @param sep Separator between groups of N elements
*   @param subSep Separator between elements within a group
*   @param labelSep Separator between labels and elements
*   @param labels Labels of each element in the group. The length of this array defines the
*                 size of the group
*   @param list Array or Vector to join
*   @return The elements of the given Array or Vector grouped as a String
*   @author Jackson Dunstan (http://JacksonDunstan.com)
*   @license MIT
*/
public static function joinNLabeled(sep:String, subSep:String, labelSep:String, labels:Array, list:*): String
{
	var n:uint = labels.length;
	var joined:String = "";
	for (var i:uint, len:uint = list.length; i < len;)
	{
		if (i)
		{
			joined += sep;
		}
		for (var j:uint = 0; j < n && i < len; ++j, ++i)
		{
			if (j)
			{
				joined += subSep;
			}
			joined += labels[j] + labelSep + list[i];
		}
	}
	return joined;
}

Spot a bug? Have a suggestion or question? Leave a comment!