ordering with cfloop
Asked Answered
I

2

6

Hi I have a loop which outputs

<cfloop collection="#SESSION.squad.achievements#" item="key">

The problem is the key(which is a year) is output in the wrong order, it outputs

2009

2010

2011

As far as I can see there in no built in method for changing the order or am I missing something?

Ironwork answered 3/5, 2011 at 9:39 Comment(0)
W
10

Coldfusion structures don't have an order, so you can't guarantee when looping over a struct that the keys will come out in the same order they were inserted (or numerically/alphabetically/etc).

If the order is important, use an array instead.

An alternative would be to get all the keys in an array, then order that array, and loop over it, but inside the loop referencing the structure.

<!--- get an array of the keys in the desired order --->
<cfset achievements = StructSort(SESSION.squad.achievements, "numeric", "desc")>

<!--- loop over that array --->
<cfloop index="year" array="#achievements#">
    <!--- refer back to the struct, keyed on the current year we're looping on --->
    #year# : #SESSION.squad.achievements[year]#
</cfloop>
Wriest answered 3/5, 2011 at 10:10 Comment(3)
You can also use the StructSort function to avoid the need to create the initial array and sort it. It's then a onestep process to get the keys in the right order before running through the loop. livedocs.adobe.com/coldfusion/8/htmldocs/…Caracal
Nice one, a function I'd forgotten about. I'll update my example code to use that instead.Wriest
good answers, would be nice to have this build in as a optional method. But is no biggie as a couple of lines sort it.Ironwork
C
2

Instead of this:

<cfset SESSION.squad.achievements = StructNew() />

Use this:

<cfset SESSION.squad.achievements = createObject("java", "java.util.LinkedHashMap").init() />

This will maintain the order.

Source: http://www.aftergeek.com/2010/03/preserving-structure-sort-order-in.html

Compass answered 30/10, 2015 at 11:22 Comment(7)
Yes. Just keep in mind that unlike CF structures, LinkedHashMap's are case sensitive. So functions like structKeyExists may return a different result if you are not careful to use the same case across the board.Psychotechnology
@Psychotechnology When I use createObject("java", "java.util.LinkedHashMap"), it orders things alphabetically. This is driving me nuts. I want it to retain definition order. What gives?Rallentando
@Psychotechnology Just an update on this. If I start the key with a capital letter, it works. But, if all the letters of the key are lower case, it orders alphabetically. Is this a bug?Rallentando
@Psychotechnology Sorry. The previous comment is wrong. Even, if I capitalise the first letter of the key, it returns the struct keys alphabetically...Rallentando
@Psychotechnology I really am an idiot. This alphabetical issue ONLY happens when I CFDUMP. If I use <cfloop>, it works correctly. Sorry people...Rallentando
@CharlesRobertson - Lol, no worries. cfdump's bias towards user friendly output gets me sometimes too. It is a great tool, but it is not always 100% "truthful" ;-)Psychotechnology
(Edit) @CharlesRobertson - Lol, cfdump's bias towards user friendly output gets me sometimes too. It is a great tool, but it is not always 100% "truthful" ;-) BTW, LinkedHashMap has some nuances you may not be expecting (example it is case sensitive). To avoid common gotchas, you may want to stick with the accepted answer.Psychotechnology

© 2022 - 2024 — McMap. All rights reserved.