开发者

JavaScript column sorting

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


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/


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/


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
*/
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜