6

I have a list of items that are not formatted consistently that I need to sort.

item 1,  item 3.0   ,item 8    ,    item 1.0 , item 4, item 5, item 6, item 10

Basically, some items could have spaces (multiple even) before or after the comma (,).

I attempted to listtoarray and then sort but I found that the sorting retained the spaces in such a way that item 1 and item 1.0 would not be sorted correctly. I thought I could use listtoarray to remove the spaces but maybe I'm thinking of a different function or perhaps I need to loop over my list via a loop?

Can someone refresh my memory on this basic task???

UPDATED Expected result should be:

item 1,item 10,item 3.0,item 4,item 5,item 6,... etc.

James A Mohler
  • 11,060
  • 15
  • 46
  • 72
HPWD
  • 2,232
  • 4
  • 31
  • 61
  • Have you tried to [`Trim`](https://helpx.adobe.com/coldfusion/cfml-reference/coldfusion-functions/functions-t-z/trim.html) the split values? – Sterling Archer Feb 22 '18 at 04:44
  • Trim would work but I'd have to loop over the list and do some processing on the individual item. If memory serves me correctly, there is something that can be done where the space gets trimmed automatically just as core nature of the function. I thought I read it on either Ben Nadel's blog or perhaps even Rayond Camden's blog a long time ago. – HPWD Feb 22 '18 at 15:41

3 Answers3

10

You can trim the spaces first and then sort. Try the below code

<cfset listA = "item 1,  item 3.0   ,item 8    ,    item 1.0 , item 4, item 5, item 6, item 10">    
<cfset b = arrayMap(listtoarray(listA),function(item,index,arr){return Trim(item)})>    
<cfset arraySort(b,"text","asc") >
<cfdump var="#b#">

enter image description here

UPDATE

This can be done using listMap also

<cfscript>
    myList="item 1,  item 3.0   ,item 8    ,    item 1.0 , item 4, item 5, item 6, item 10";
    myList=ListMap(myList,function(item){return Trim(item);});
    myList = listSort(myList, "textnocase", "asc");     
    writeOutput(myList);
</cfscript>
Vineesh
  • 3,762
  • 20
  • 37
3

For a regex option you can use the match pattern \s*,\s*. This pattern reads as match any , with 0 or more whitespace characters before and 0 or more whitespace characters after. Then we can use reReplace to replace these matches with a , with no spaces.

<cfscript>
    myList="item 1,  item 3.0   ,item 8    ,    item 1.0 , item 4, item 5, item 6, item 10";
    myList = reReplace(trim(myList), "\s*,\s*", ",", "all");
    myList = listSort(myList, "textnocase", "asc");
    writeOutput(myList);
</cfscript>

TryCF.com example
regex101.com example

Twillen
  • 1,458
  • 15
  • 22
  • I just saw this and wow, that was surprisingly much easier than I thought. Makes me want to brush up on my regex skills! – user9263373 Mar 11 '18 at 23:57
  • @user9263373 I learned the basics of regex with the website https://regexone.com. Definitely a great skill to have. – Twillen Mar 12 '18 at 16:47
2

Here's another way using the same basic idea. Loop through the list items and trim them, then finally sort. Working example here

<cfscript>
    myList = "item 1,  item 3.0   ,item 8    ,    item 1.0 , item 4, item 5, item 6, item 10";

    i = 1;
    for (item in myList) {
        myList = listSetAt(myList, i, trim(item));
        i++;
    }

    myList = listSort(myList, "textnocase", "asc");    

    writeOutput(myList);
</cfscript>
user9263373
  • 1,054
  • 8
  • 15
  • I upvoted this as this is does work (and you used cfscript +1) and does answer my looping question but I still think there is another function that will do this too. – HPWD Feb 22 '18 at 15:43
  • @HPWD Thanks for the upvote. Btw, I don't believe there's a way to to it without looping unless perhaps you're a regex guru (I don't come even close to qualifying) and using `reReplace()`. – user9263373 Feb 22 '18 at 16:04
  • @HPWD Challenge... update your question with a bounty to see if someone can do this using regular expression only :) – user9263373 Feb 22 '18 at 16:31