2

What is the best way of sorting if the column values are:

Before SORTING:

CANCELLED,
v06.*,
INDEPENDENT,
v06.00,
v06.00.01,
v06.01,
v06.02,
v06.00.xx,
v06.03,
v06.04,
ON HOLD,
v06.06,
v06.05,
v06.05.01,
v06.04.01,
v06.05.02,
v06.07,
v07.00,

After SORTING:

  CANCELLED,
  INDEPENDENT,
  ON HOLD,
  v06.*,
  v06.00,
  v06.00.01,
  v06.00.xx,
  v06.01,
  v06.02,
  v06.03,
  v06.04,
  v06.04.01,
  v06.05,
  v06.05.01,
  v06.05.02,
  v06.06,
  v06.07,
  v07.00

Thanks in advance, Joseph

2
  • 1
    Column vaLues? This vague. Do you mean a bunch of table cells in a column or just some array values returned from somewhere? Commented Dec 9, 2010 at 14:15
  • Also, presumably you mean JavaScript. Please change the title to say that. Java is a very different language and it might cause confusion. (Thanks!) Commented Dec 9, 2010 at 14:17

3 Answers 3

1

First sort it alphabetically ascending (by the 'default' sort - or sort() without passing a function), then sort it numerically. That said, I'm sure there is a better way:

function sortNumber(a, b) {
    return a - b;
}

var arr = [
    "v07.00", "CANCELLED", "v06.*", "v06.04.01", "INDEPENDENT", "v06.00", "v06.00.01",
    "v06.01", "v06.02", "v06.00.xx", "v06.03", "v06.04", "ON HOLD",
    "v06.06", "v06.05", "v06.05.01", "v06.05.02",
    "v06.07",
];
alert(arr.sort().sort(sortNumber).join("\n"));

Demo: http://jsfiddle.net/karim79/rY8Du/1/

Sign up to request clarification or add additional context in comments.

Comments

1

Assuming your "column values" are in an Array, use Array.sort with a custom compareFunction to define the ordering as you want.

var columnValues = [
  "CANCELLED", "v06.*", "INDEPENDENT", "v06.00", "v06.00.01",
  "v06.01", "v06.02", "v06.00.xx", "v06.03", "v06.04", "ON HOLD",
  "v06.06", "v06.05", "v06.05.01", "v06.04.01", "v06.05.02",
   "v06.07", "v07.00" ];
columnValues.sort(function(a, b) {
   if (a is less than b by some ordering criterion)  
      return -1;  
   if (a is greater than b by the ordering criterion)  
      return 1;  
   // a must be equal to b  
   return 0;  
});

Edit here's a long-winded compareFunction that seems to do what you want, at least for the example you give:

function(a, b) {
    if (a==b) {
        return 0;
    }
    if (a.length && a[0]=='v' && b.length && b[0]=='v') {
        // Both strings are version strings.
        // Do special case version matching.
        var aParts = a.substring(1).split('.'),
            bParts = b.substring(1).split('.'),
            l = Math.max(a.length, b.length),
            i = 0;
        for (;i<l;i++) {
            var aPart = aParts[i],
                bPart = bParts[i];
            if (aPart == '*' && bPart != '*') {
                return -1;
            }
            if (bPart == '*' && aPart != '*') {
                return 1;
            }
            if (aPart == 'xx' && bPart != 'xx') {
                return 1;
            }
            if (bPart == 'xx' && aPart != 'xx') {
                return -1;
            }
            var aNum = parseInt(aPart,10),
                bNum = parseInt(bPart,10);
            if (aNum < bNum) {
                return -1;
            }
            if (aNum > bNum) {
                return 1;
            }
            // Same so far, try next part
        }
        // One must be longer than the other.
        return (aParts.length < bParts.length) ? -1 : 1
    }
    // Simple alphabetic comparison
    if (a < b)
        return -1;
    if (a > b)
        return 1;
}

Demo: http://jsfiddle.net/daybarr/h6nmg/

Comments

0

Once you get the column into an array you can use any natural sort method, but you'll need to write a couple extra lines to sort the '*' the way you want.

Here is one sample-

function natSort(as, bs){
    var a, b, a1, b1, i= 0, L, rx=  /(\d+)|(\D+)/g, rd=  /\d/;
    if(isFinite(as) && isFinite(bs)) return as - bs;
    a= String(as).toLowerCase();
    b= String(bs).toLowerCase();
    if(a=== b) return 0;
    if(!(rd.test(a) && rd.test(b))) return a> b? 1: -1;

    a=a.replace('*','0'); // or possibly sort any non alpha nums first:
    b=b.replace('*','0'); // replace(/[^\w\.]/g,'0');

    a= a.match(rx);
    b= b.match(rx);
    L= a.length> b.length? b.length: a.length;
    while(i < L){
        a1= a[i];
        b1= b[i++];
        if(a1!== b1){
            if(isFinite(a1) && isFinite(b1)){
                if(a1.charAt(0)=== "0") a1= "." + a1;
                if(b1.charAt(0)=== "0") b1= "." + b1;
                return a1 - b1;
            }
            else return a1> b1? 1: -1;
        }
    }
    return a.length - b.length;
}

var v= "v06.05,ON HOLD,v07.00,INDEPENDENT,v06.07,v06.03,v06.*,v06.05.02,v06.05.01,"+
"v06.00.xx,v06.00,CANCELLED,v06.02,v06.04,v06.00.01,v06.06,v06.01,v06.04.01";
v=v.split(/, */);

'before sort:\n'+v.join(',\n')+'\n\nafter sort:\n'+ v.sort(natSort).join(',\n')


/*  returned value:
before sort:
v06.05,
ON HOLD,
v07.00,
INDEPENDENT,
v06.07,
v06.03,
v06.*,
v06.05.02,
v06.05.01,
v06.00.xx,
v06.00,
CANCELLED,
v06.02,
v06.04,
v06.00.01,
v06.06,
v06.01,
v06.04.01

after sort:
CANCELLED,
INDEPENDENT,
ON HOLD,
v06.*,
v06.00,
v06.00.01,
v06.00.xx,
v06.01,
v06.02,
v06.03,
v06.04,
v06.04.01,
v06.05,
v06.05.01,
v06.05.02,
v06.06,
v06.07,
v07.00
*/

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.