Search code examples
structcoldfusion

How can I preserve the assign order in a structure in ColdFusion <2016


ColdFusion doesn't preserve the order in which elements were assigned to the structure.
This gives a problem when, in my particular case, I need to create a SOAP envelope from this structure and the receiver needs to data in the envelope in a particular order.
Starting from ColdFusion 2016 and higher, there is a "type" option in the StructNew() method where you can specify "Ordered". Unfortunately, I'm still on CF9.02... For example (in CF9):

<cfscript>
       myStruct=StructNew();
       myStruct.one=StructNew();
       myStruct.one.item1="Old Trafford";
       myStruct.one.item2="Anfield";
       myStruct.two=StructNew();
       myStruct.two.item3="Stamford Bridge";
       myStruct.two.item4="Villa Park";
       myStruct.three=StructNew();
       myStruct.three.item5="St James Park";
       myStruct.three.item6="Emirates Stadium";
       WriteDump(myStruct);
</cfscript>

Output:

{"ONE":{"ITEM2":"Anfield","ITEM1":"Old Trafford"},"THREE":{"ITEM6":"Emirates Stadium","ITEM5":"St James Park"},"TWO":{"ITEM4":"Villa Park","ITEM3":"Stamford Bridge"}}

As you can see, the order is scrambled.

A second problem is the UPPERCASE. All the items are transformed to uppercase...
This is a problem for a SOAP envelope, because it is case sensitive.


Solution

    1. Order.
      The solution is to use a java LinkedHashMap which can be used just like a structure in ColdFusion.
      So, I just need to replace StructNew();
      with: createObject("java", "java.util.LinkedHashMap").init();

    2. Uppercase:
      Assign/address them though their string name. This will preserve the case.

    So, the example becomes:

    <cfscript>
           myStruct=createObject("java", "java.util.LinkedHashMap").init();
           myStruct['one']=createObject("java", "java.util.LinkedHashMap").init();
           myStruct['one']['item1']="Old Trafford";
           myStruct['one']['item2']="Anfield";
           myStruct['two']=createObject("java", "java.util.LinkedHashMap").init();
           myStruct['two']['item3']="Stamford Bridge";
           myStruct['two']['item4']="Villa Park";
           myStruct['three']=createObject("java", "java.util.LinkedHashMap").init();
           myStruct['three']['item5']="St James Park";
           myStruct['three']['item6']="Emirates Stadium";
           WriteDump(SerializeJSON(myStruct));
    </cfscript>
    

    Output:

    {"one":{"item1":"Old Trafford","item2":"Anfield"},"two":{"item3":"Stamford Bridge","item4":"Villa Park"},"three":{"item5":"St James Park","item6":"Emirates Stadium"}}
    

    Nicely ordered and case preserved!