Saturday, June 02, 2007

ListToArray with empty elements - Part II

Yesterday I had posted about how to convert List to Array that would include empty elements. Charlie rightly pointed out a problem with that which is - it does not consider the empty elements at the end of the list.
So, a list "a,b,,c,d,," when converted to array will have only 5 elements instead of 7.

Incidently Charlie had also talked about the same some time back here and he mentions another problem with this approach. The array that is returned after split method is read only and you can not modify this array.
In order to address both these, I had to write this UDF which I guess many people would have written anyways..





<cfscript>
function list2Array(list)
{
var endCommaCount = 0;
var i = 0; var c = "";
var stringForSplit = ""; var retList=""; var arr = "";

for(i=len(list); i > 0; i--)
{
c = list.charAt(i-1);
if(c == ',')
endCommaCount++;
if( c != ',' && c != ' ')
break;
}
retlist = ArrayNew(1);

if(i != 0)
{
stringForSplit = left(list, i);
arr = stringForSplit.split("\s*,\s*");

for(i = 1; i <= ArrayLen(arr); i++)
ArrayAppend(retList, arr[i]);
}

for(i = 0; i < endCommaCount; i++)
ArrayAppend(retList, "");

return retList;
}
</cfscript>



UPDATE : Thanks to Andrew Clark for the split tip which makes it more slim and elegant. The code above changes like



<cfscript>
function list2Array(list)
{
var i = 0;
var retlist = ArrayNew(1);
var arr = list.split(",", -1);
for(i = 1; i <= ArrayLen(arr); i++)
ArrayAppend(retList, arr[i]);
return retList;
}
</cfscript>

Lets test this udf and see if it works..


<cfset cflist = "a,b,,c,,d, ,">
<cfset cfarr1 = ListToArray(cflist)>
<cfset ArrayAppend(cfarr1, "END")>
<cfset cfarr2 = List2Array(cflist)>
<cfset ArrayAppend(cfarr2, "END")>

With CF Function : <cfdump var="#cfarr1#" format="text">
With UDF : <cfdump var="#cfarr2#" format="text">


And this produces this result.
With CF Function :
array - Top 6 of 6 rows

1) a
2) b
3) c
4) d
5)
6) END
With UDF :
array - Top 9 of 9 rows

1) a
2) b
3) [empty string]
4) c
5) [empty string]
6) d
7) [empty string]
8) [empty string]
9) END


One thing to note here is that I am using new cfscript operators added in ColdFusion 8 which is so cool!!!

4 comments:

Anonymous said...

this only works in CF 8!!!

Rupesh Kumar said...

yeah.. It works only on CF 8 because it uses the new syntax which was another of my purpose. For it to work on CF 7, all you need to do is to change the loop construct. i.e the loop should look something like
for(i = 1; i LE ArrayLen(arr); i = i+1)
{
...
}

Giancarlo Gomez said...

The code for a CF 7 function is as follows:

function list2Array(list)
{
var i = 0;
var retlist = ArrayNew(1);
var arr = list.split('","');
for(i = 1; i LTE ArrayLen(arr); i=i+1)
ArrayAppend(retList,arr[i]);
return retList;
}

Unknown said...

This post still holds up! Had a heck of time parsing a csv which had a header row that had two words (user id). All the other fancy tricks can't compare to that great script you wrote! Thanks so much!!