Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Any better way to loop through a collection (struct) in CFML?

Please have a look at the code block below:

<cfset index = 0 />
<cfloop collection="#anotherPerson#" item="key" >
    <cfset index = index+1 />
    <cfoutput> 
         #key# : #anotherPerson[key]# 
         <cfif index lt ArrayLen(structKeyArray(anotherPerson))> , </cfif>
    </cfoutput>
</cfloop>

<!--- Result 

   age : 24 , haar : Blondes haar , sex : female , ort : Hanau

---->

Now can you please tell me how could I achieve the same result without setting an index outside and incrementing it inside the loop? If you notice carefully, I had to write two more cfset tag and one cfif tag with expensive code just to avoid a comma (,) at the end of the collection!

like image 672
edam Avatar asked Sep 18 '25 02:09

edam


2 Answers

Ok, I'm showing you two answers. The first will run on ColdFusion 9. Since other people might find this thread and be using Lucee Server or a newer version of Adobe ColdFusion, I'm including a one-liner that uses higher order functions and runs on ACF 2016. There's a lot of syntactic sugar (like member functions) and functional programming you're missing by being on CF9. These answers use script, because manipulating data is not something for a view (where tags/templating are used).

Set up the data

myStruct = { 'age'=24, 'haar'='Blondes haar', 'sex'='female', 'ort'='Hanau' };

CF9 compat, convert data to array and use delimiter to add commas

myArray = [];
for( key in myStruct ) {
    arrayAppend( myArray, key & ' : ' & myStruct[ key ] );
}
writeOutput( arrayToList( myArray, ', ' ) );

Modern CFML. Use struct reduction closure to convert each key into an aggregated array which is then turned into a list.

writeOutput( myStruct.reduce( function(r,k,v,s){ return r.append( k & ' : ' & s[ k ] );  }, [] ).toList( ', ' ) );

http://cfdocs.org/structreduce

like image 54
Brad Wood Avatar answered Sep 20 '25 22:09

Brad Wood


Some friends provided two different solutions. Both are efficient and elegant!

Solution 1

<cfset isFirst = true />
<cfloop collection="#anotherPerson#" item="key" >
    <cfif isFirst>
        <cfset isFirst = false />
    <cfelse> 
        ,   
    </cfif> 
    <cfoutput> 
       #key# : #anotherPerson[key]# 
    </cfoutput>
</cfloop>

Solution 2

<cfset resultList = "" />
<cfloop collection="#anotherPerson#" item="key" >
    <cfset resultList = ListAppend(resultList, "#key# : #anotherPerson[key]#" ) />
</cfloop>

Cheers!

like image 23
edam Avatar answered Sep 20 '25 22:09

edam