6

I need to sort an array of alphanumerical items as follows. From:

2 xxx
20 axxx
38 xxxx
20 bx
8540 xxxxxx

to:

8540 xxxxx
38 xxxx
20 axxx
20 bx
2 xxx

Thus, sorted descending with respect to the numbers, then ascending alphabetically. The numbers are always separated from the alphabetical characters (denoted "xxxx") by a single space, but the numbers are variable length.

I suspect I need to use some Regex in the sort() function and splitting off the numbers by the space then sorting it, but I don't know how to tie in the alphabetical sorting. Any code samples? Thanks so much!

zdebruine
  • 3,687
  • 6
  • 31
  • 50
  • Check out these answers to see if you can adapt the solution: http://stackoverflow.com/a/4321879/1375372 http://stackoverflow.com/a/11931192/1375372 http://stackoverflow.com/a/4340339/1375372 – Rob Grzyb Jun 10 '13 at 03:20

2 Answers2

6

No need for RegEx, because Array.sort() accepts custom function:

http://jsfiddle.net/EFGK9/

var arr=["2 xxx","20 axxx","38 xxxx","20 bx","8540 xxxxxx"];
arr.sort(function(a,b){
    a=a.split(" ");
    b=b.split(" ");
    var an=parseInt(a[0],10);
    var bn=parseInt(b[0],10);
    return an<bn?1:(an>bn?-1:(a[1]<b[1]?-1:(a[1]>b[1]?1:0)));
});
console.log(arr);
Passerby
  • 9,715
  • 2
  • 33
  • 50
  • 1
    The OP knows that `.sort()` accepts a custom function; they were wondering about using regex within that function (although, as you've pointed out, `.split()` is enough in this case, a more complicated input format might call for regex). – nnnnnn Jun 10 '13 at 03:38
4

Something like this will work:

var arr = [
    "2 xxx",
    "20 axxx",
    "38 xxxx",
    "20 bx",
    "8540 xxxxxx"
    ];

arr.sort(function(a, b) {
    var aParts = a.split(" "),
        bParts = b.split(" "),
        aNum = +aParts[0],   // convert numeric parts
        bNum = +bParts[0];   // to actual numbers

    if (aNum > bNum)
        return -1;
    else if (aNum < bNum)
        return 1;
    else
        return aParts[1].localeCompare(bParts[1]);
});

Demo: http://jsfiddle.net/KLa2J/

nnnnnn
  • 147,572
  • 30
  • 200
  • 241
  • Just as a side note, the jsfiddle hasn't been working for me. I see how this theoretically should work, but the split(" ") function seems to have issues. Thanks for the good answer anyways! – zdebruine Jun 10 '13 at 10:34
  • 1
    I don't see how `.split(" ")` could be causing you problems when the answer you accepted uses the same technique. You're not trying to test the fiddle with an old version of IE? I included a `console.log()` statement, which gives an error in old IE if the console isn't actually open at the time, but otherwise it works fine. – nnnnnn Jun 10 '13 at 10:52
  • Ah, I see. The jsfiddle doesn't work for me in the newest version of Chrome – zdebruine Jun 10 '13 at 17:12
  • Weird. The latest Chrome (under Windows) is what I'm using. Oh well. – nnnnnn Jun 10 '13 at 22:02