user125264
user125264

Reputation: 1827

sorting array by custom order in Coldfusion

Ive got an array of product sizes which can be varied.

some cases it will be.

08
10
12
16
18
S
M
L
XL
XXL

I appear to be able to sort the array of numeric values easily, however when the sizing has strings with it also, i cant seem to sort them in alphabetical order as well

Example it ends up being

L
M
S
XL
XXL

technicailly speaking, this is correct for alphabetical order, but the order for it for human beings should be

S
M
L
XL
XXL

Would anyone know of a way to do this using Coldfusion ? Im currently using CF 8 and have looked everywhere for sorting, but cant seem to find out how to do it

Upvotes: 1

Views: 1465

Answers (2)

Henry
Henry

Reputation: 32915

If you're using CF10+, you're in luck!

https://wikidocs.adobe.com/wiki/display/coldfusionen/ArraySort

Implement your own callback function to sort your collection yourself, e.g.:

<cfscript>
    function sortSize(array sizes) 
    {
        var sizeOrder = "XXS,XS,S,M,L,XL,XXL";    // your sort order

        arraySort(sizes, function(s1, s2) {
            return listFindNoCase(sizeOrder,s1) - listFindNoCase(sizeOrder,s2);
        });

        return sizes;
    }
</cfscript>

Run the code above on TryCF: http://www.trycf.com/scratch-pad/pastebin?id=pb1rn6CT

Update: But since you're using CF8, you can implement your own bubble sort and try:

<cfscript>
    function sortSize(input) 
    {
        var local = {};

        local.sizes = "XXS,XS,S,M,L,XL,XXL";    // your sort order
        local.sorted = false;
        local.inputSize = arrayLen(input);

        while (!local.sorted) 
        {
            local.sorted = true;
            for (local.i = 1; local.i < local.inputSize; local.i = local.i + 1) 
            {
                local.size1 = listFindNoCase(local.sizes, input[local.i]);
                local.size2 = listFindNoCase(local.sizes, input[local.i + 1]);

                if (local.size1 > local.size2)
                {
                    arraySwap(input, local.i, local.i + 1);
                    local.sorted = false;
                }
            }
        }

        return input;
    }
</cfscript>
<cfdump var="#sortSize(listToArray('l,M,M,s,XL,Xs'))#">

Run the code above on TryCF: http://www.trycf.com/scratch-pad/pastebin?id=uL7r9Uyf

Upvotes: 4

Gerry Gurevich
Gerry Gurevich

Reputation: 936

Personally, I don't want to go back to figuring out bubble, merge, or any other sorting algorithm. I might take the following steps:

  1. Set up a database table of all possible sizes with a numeric column for some sort of sorting criteria.
  2. Cache or create that query in a application level singleton
  3. Create a UDF that would convert your array to a query using CF8's version of QueryNew and it's affiliated functions.
  4. Do a query of queries joining your sorted sizes to your unsorted array and order by the sortfield
  5. Make sure you do a left join and make sure you capture the sizes that don't fit your original table so that you can error, report, or randomize, any data that comes in mismatched.

Encapsulate the entire process into a UDF or method of an application scoped singleton for repeated calls.

Upvotes: 3

Related Questions