I posted this as a solution to CF-Talk the other day and I thought I would post it here as well (for some reason, not everyone and their mother subscribes to CF-Talk??). Paul Vernon wanted to create an on-screen ASCII ruler that would fully display the powers of 10 (10, 20, 30... 150, 160, etc) but for each non-power-of-10, only display the ones digit (1,2,3,4,5,67,8,9).
My solution builds the output into a two dimensional array. I was treating each character in the output as a sepparate index in the array. Places that has no digit were given a white space character. Then the array is converted to a string using a Java StringBuffer.
I am not 100% sure what this would ever be used for, but here goes:
<!--- Get the length of the ASCII ruler. ---> <cfset intRulerLength = 150 /> <!--- Get the ruler height. This is the number of digits that the max value will have. Since the rule will count up from 1, the max height will be determined by the last value in the ruler (ie. the length of the ruler). ---> <cfset intRulerHeight = Len( intRulerLength ) /> <!--- Create the array in which to build the output. This is a two-dimensional array. The first index is going to create the ROW of the output (digit column). The Second index is going to be the COLUMN of the output (the index on the ruler. ---> <cfset arrRuler = ArrayNew( 2 ) /> <!--- Now, let's start building the ruler output by looping from 1 to the length of the ruler. ---> <cfloop index="intColumn" from="1" to="#intRulerLength#"> <!--- Check to see if we are at a power of 10 (MOD will not return a remainder). If we are, then we need to display all digits, otherwise, we are just going to display the ones digit column. ---> <cfif (intColumn MOD 10)> <!--- Fill the entire column with spaces. ---> <cfloop index="intDigit" from="1" to="#intRulerHeight#"> <cfset arrRuler[ intDigit ][ intColumn ] = " " /> </cfloop> <!--- Now that we have filled the column with spaces, put the ones digit in the last space. ---> <cfset arrRuler[ intRulerHeight ][ intColumn ] = (intColumn MOD 10) /> <cfelse> <!--- We need to output the entire value in the output. But, this value might not be the same length as the max value length. Therefore, we need to right-justify the value to fit exactly with the ruler's height. ---> <cfset strValue = RJustify( intColumn, intRulerHeight ) /> <!--- Now loop over the value and apply to the ruler output array. ---> <cfloop index="intDigit" from="1" to="#intRulerHeight#"> <cfset arrRuler[ intDigit ][ intColumn ] = Mid( strValue, intDigit, 1 ) /> </cfloop> </cfif> </cfloop> <!--- ASSERT: At this point, the entire output for the ASCII ruler should be stored in the ruler array. Now, we need to translate that into a horizontal ruler. To make this faster and control the white space, let's create a Java string buffer to which we can systematically append output data. ---> <cfset sbOutput = CreateObject( "java", "java.lang.StringBuffer" ).Init() /> <!--- Loop over the ruler array and append to output. Since we need to output the ruler horizontally, we need to do each row at a time. ---> <cfloop index="intDigit" from="1" to="#intRulerHeight#"> <!--- For each row of digits, loop over every column. ---> <cfloop index="intColumn" from="1" to="#intRulerLength#"> <!--- When appending, we need to convert the array data to a string to make sure Java don't choke. ---> <cfset sbOutput.Append( JavaCast( "string", arrRuler[ intDigit ][ intColumn ] ) ) /> </cfloop> <!--- After each row, add a line break. ---> <cfset sbOutput.Append( JavaCast( "string", Chr( 13 ) & Chr( 10 ) ) ) /> </cfloop> <!--- Output the ASCII data in PRE tags for best formatting. ---> <pre>#sbOutput.ToString()#</pre>
This gives us output that looks like this:
So, not sure what this is used for, but that's one solution.