This was discussed on my forums a few days ago, but as I rarely see structSort "in the field", I thought I'd share a simple example.

The user had a simple structure where every key was a name and the value was an age. For example:


His goal was to display the names in order of their age. structSort can handle this very simply. The structSort argument takes 4 arguments:

  • First is the structure you are sorting.
  • Second is the sort type. This can be numeric, text (default), or textnocase.
  • Third is sortOrder, which is asc or desc (no true or false, ahem, are you listening Transfer?)
  • Last is pathToSubElement. That one is a bit scary, so just pretend it doesn't exist for a few minutes.

The result is an array of keys sorted in the right order. So taking the simple desire to sort by age, we can use:

<cfset s = {bob=93,ted=90,jane=94,al=91}> <cfdump var="#s#"> <cfset sorted = structSort(s, "numeric")> <cfdump var="#sorted#">

And that's it. Well, you probably don't want to use dump to format your data. Since we have an array of keys as a result, here is how I'd actually display it:

<cfset s = {bob=93,ted=90,jane=94,al=91}> <cfset sorted = structSort(s, "numeric")>

<cfloop index="name" array="#sorted#"> <cfoutput>#name# is #s[name]# years young.<br/></cfoutput> </cfloop>

Notice I use the new index/array form of cfloop. If you are on CF7, you would loop from 1 to arrayLen(sorted). The results:

TED is 90 years young.
AL is 91 years young.
BOB is 93 years young.
JANE is 94 years young.

Ok, simple enough, right? What if you want to use that super-special fourth argument I told you was too scary? Well, it really isn't too scary. It comes in handy if you wan to sort structures that aren't as simple as the example above. Consider this data:

<cfset s2 = {}> <cfset s2.ray = {age=36,rank="General"}> <cfset s2.scott = {age=42,rank="Private"}> <cfset s2.todd = {age=29,rank="Major"}> <cfset s2.fred = {age=51,rank="Corporal"}>

In this example, instead of simple values, every key is itself a structure containing an age and rank value. This is where the fourth argument comes into play. We can now sort by age or rank:

<cfset sortedByAge = structSort(s2, "numeric", "asc", "age")> <cfdump var="#sortedByAge#" label="sorted by age">

<cfset sortedByRank = structSort(s2, "textnocase", "asc", "rank")> <cfdump var="#sortedByRank#" label="sorted by rank">

Which outputs:

I hope this helps. And yes - I know the rank sort isn't sorting by the proper military hierarchy. You would have to write custom code to handle that yourself.