Search code examples
coldfusioncoldfusion-8

Sorting an implicit array of implicit structs by struct key


Based on the first example in this blog post, I have an implicit array of implicit structs. My data is actually pretty similar, e.g.:

<cfset ReportsArray = [
  {
    Name = "My First Report",
    Group = "Group One"
  },
  {
    Name = "My Second Report",
    Group = "Group Two"
  },
  {
    Name = "My Third Report"
    Group = "Group One"
  },
  ...etc...
]>

I decided to create the data in this format so that I can later push a new report to the array in any group, or just rewrite the array with a new list of reports if needed. I'm wondering if it's possible to sort this array based on the "Group" key in the structs so that I can loop through them and output something like this:

Group One

My First Report

My Third Report

Group Two

My Second Report

--

Does that make sense? Or am I going about this wrong?


Solution

  • Maybe Query would be the right data type for the right job? with ColdFusion's famous Query of Queries, sorting data like this is a piece of cake.

    If you really want to sort an array of objects, and you're in CF10+, you are in luck. You may use ArraySort with callback: https://wikidocs.adobe.com/wiki/display/coldfusionen/ArraySort.

    If you insist, here's a easy to read bubble sort that would work in CF8:

    <cfscript>
    
        function sortReports(reports) 
        {
            var local = {};
    
            local.sorted = false;
            local.reportSize = arrayLen(reports);
    
            while (!local.sorted) 
            {
                local.sorted = true;
                for (local.i = 1; local.i < local.reportSize ; local.i = local.i + 1) 
                {
                    local.report1 = reports[local.i];
                    local.report2 = reports[local.i + 1];
    
                    if (local.report1.group > local.report2.group)
                    {
                        arraySwap(reports, local.i, local.i + 1);
                        local.sorted = false;
                    }
                }
            }
    
            return reports;
        }
    
    reportsArray = [
      {
        Name = "My First Report",
        Group = "Group One"
      },
      {
        Name = "My Second Report",
        Group = "Group Two"
      },
      {
        Name = "My Third Report",
        Group = "Group One"
      }
    ];
    </cfscript>
    <cfdump var="#sortReports(reportsArray)#">
    

    Run it here: http://www.trycf.com/scratch-pad/pastebin?id=RuSHgZYq