-1

I am trying to sort an array in a specific way and I'm trying to do it efficiently, preferably with the .sort() function. Here is as example of the kind of array I need to work with:

["10", "11", "12", "13", "2", "3", "4", "5", "6", "7", "8", "9", "2a", "2s", "3a"]

Here is what i am looking for after the sort:

["13", "12", "11", "10", "9", "8", "7", "6", "5", "4", "3", "3a", "2s", "2", "2a"]

rules:

sort integer values in descending order. integers that have an "a" appended have a lesser value. integers appended with an "s" have a greater value. Therefore, 2a would be inbetween 2 and 1, and 2s would be inbetween 3 and 2. 3a would be greater than 2s.

please help!

Zyren
  • 603
  • 2
  • 7
  • 21
  • You can provide a [compareFunction to sort](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/sort) that uses whatever logic you like to sort members. – RobG Mar 08 '12 at 00:43
  • 1
    You realize that array will cause an illegal token error? Do you mean for them all to be strings? – calebds Mar 08 '12 at 00:44
  • yes they are all strings. my bad. – Zyren Mar 08 '12 at 00:54

2 Answers2

2

Here's a ways to use the javascript .sort() function. Since you want to allow "2a" and "2s", I'm assuming that all input is strings.

Working demo here: http://jsfiddle.net/jfriend00/NDbcC/

var input = ["10", "11", "12", "13", "2", "3", "4", "5", "6", "7", "8", "9", "2a", "2s", "3a"];

var suffix = {"s": 1, "a": -1, 
      "0": 0, "1": 0, "2": 0, "3": 0, "4": 0, "5": 0, 
      "6": 0, "7": 0, "8": 0, "9": 0};

input.sort(function(a, b) {
    var numA = parseInt(a, 10), numB = parseInt(b, 10);
    if (numA == numB) {
        numB = suffix[b.charAt(b.length - 1)];
        numA = suffix[a.charAt(a.length - 1)];
    }
    return(numB - numA);
});

//output is: 
// ["13", "12", "11", "10", "9", "8", "7", "6", "5", "4", "3", "3a", "2s", "2", "2a"]
jfriend00
  • 683,504
  • 96
  • 985
  • 979
1

Basically, you need to parse the numbers out and compare on those, adding 1 if the following character is "a" and subtracting 1 if the following character is "s" (because it's a reverse order sort).

This is what I came up with, it will work on an array of all strings or one with mixed strings and numbers:

var weirdSort = (function () {
    var chr = String.prototype.charAt,
        add = {a:1, s:-1};

    return function (a, b) {
        var intA = parseInt(a), intB = parseInt(b);

        if (intA === intB) {
            if (isNaN(a))
                intB = intA + add[chr.call(a, 1)];

            if (isNaN(b))
                intA = intB + add[chr.call(b, 1)];
        }

        return intB - intA;
    }
})();

[10, 11, 12, 13, 2, 3, 4, 5, 6, 7, 8, 9, "2a", "2s", "3a"].sort(weirdSort);
//-> [13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, "3a", "2s", 2, "2a"]

There might be an easier way, but I think my brain can be excused for not working at full capacity at 1am.

Andy E
  • 338,112
  • 86
  • 474
  • 445