admin管理员组

文章数量:1291102

Ok I have a section of code that sorts the names it is given alphabetically.

However the code doesnt handle decimals the way I would want.

It orders the name in the following manner (Obv I would rather it incremented numerically):

It would order it:

  • APPLE - 1.0051
  • APPLE - 1.1071
  • APPLE - 11.1592
  • APPLE - 12.0692
  • APPLE - 12.1717
  • APPLE - 2.0186 << this should be after "APPLE - 1.1071" obviously
  • APPLE - 21.1407
  • APPLE - 22.089
  • APPLE - 23.069
  • BANANA - 1.0051
  • BANANA - 1.1071
  • BANANA - 11.1592
  • BANANA - 12.0692
  • BANANA - 12.1717
  • BANANA - 2.0186 << this should be after "BANANA - 1.1071" obviously
  • BANANA - 21.1407
  • BANANA - 22.089
  • BANANA - 23.069

Here is the code I am using. I do not fully understand the code as it was a snippet I have been using.

function(a, b){
         var nameA=a.myname.toLowerCase(), nameB=b.myname.toLowerCase()
         if (nameA < nameB) //sort string ascending
          return -1 
         if (nameA > nameB)
          return 1
         return 0 //default return value (no sorting)
    }

Regards, Jonny

Ok I have a section of code that sorts the names it is given alphabetically.

However the code doesnt handle decimals the way I would want.

It orders the name in the following manner (Obv I would rather it incremented numerically):

It would order it:

  • APPLE - 1.0051
  • APPLE - 1.1071
  • APPLE - 11.1592
  • APPLE - 12.0692
  • APPLE - 12.1717
  • APPLE - 2.0186 << this should be after "APPLE - 1.1071" obviously
  • APPLE - 21.1407
  • APPLE - 22.089
  • APPLE - 23.069
  • BANANA - 1.0051
  • BANANA - 1.1071
  • BANANA - 11.1592
  • BANANA - 12.0692
  • BANANA - 12.1717
  • BANANA - 2.0186 << this should be after "BANANA - 1.1071" obviously
  • BANANA - 21.1407
  • BANANA - 22.089
  • BANANA - 23.069

Here is the code I am using. I do not fully understand the code as it was a snippet I have been using.

function(a, b){
         var nameA=a.myname.toLowerCase(), nameB=b.myname.toLowerCase()
         if (nameA < nameB) //sort string ascending
          return -1 
         if (nameA > nameB)
          return 1
         return 0 //default return value (no sorting)
    }

Regards, Jonny

Share Improve this question asked Jan 26, 2013 at 18:51 JonnyJonny 3692 gold badges5 silver badges8 bronze badges 1
  • 3 Right now you are sorting by text strings (ascii sort). You could put leading zeroes on the numbers: 01.0001, or you'll have to split the numbers out of the string, convert them and then sort by two fields. – Steve Wellens Commented Jan 26, 2013 at 18:54
Add a ment  | 

5 Answers 5

Reset to default 3

Demo and here is the source + small explanation:

function fruit_sort(a, b) {
    var parts = {
        a: a.split('-'),
        b: b.split('-')
    };
    if (parts.a[0] == parts.b[0]) // strings are the same
        return parseFloat(parts.a[1]) - parseFloat(parts.b[1]); // sort by number
    return parts.a[0] > parts.b[0] ? 1 : -1; // sort by string
}
var arr = ["APPLE - 1.0051",
    "APPLE - 1.1071",
    "APPLE - 11.1592",
    "APPLE - 12.0692",
    "BANANA - 1.0051",
    "BANANA - 1.1071",
    "BANANA - 11.1592",
    "BANANA - 12.0692",
    "BANANA - 12.1717",
    "APPLE - 12.1717",
    "APPLE - 2.0186",
    "APPLE - 21.1407",
    "BANANA - 23.069",
    "APPLE - 22.089",
    "APPLE - 23.069",
    "BANANA - 2.0186",
    "BANANA - 21.1407",
    "BANANA - 22.089"];
arr.sort(fruit_sort);
console.log(arr);
// outputs
[
    "APPLE - 1.0051",
    "APPLE - 1.1071",
    "APPLE - 2.0186",
    "APPLE - 11.1592",
    "APPLE - 12.0692",
    "APPLE - 12.1717",
    "APPLE - 21.1407",
    "APPLE - 22.089",
    "APPLE - 23.069",
    "BANANA - 1.0051",
    "BANANA - 1.1071",
    "BANANA - 2.0186",
    "BANANA - 11.1592",
    "BANANA - 12.0692",
    "BANANA - 12.1717",
    "BANANA - 21.1407",
    "BANANA - 22.089",
    "BANANA - 23.069"
]

First the function splits the terms up into their text and numerical parts - if the text is even it only sorts on the parseFloat value of the numerical value - otherwise it sorts first by the string value.

Like @Steve Wellens suggested in his ment, I modified your existing snippet to pare the text parts first, then in the event of a tie pare the numeric portions of the string, by converting them to floats. If you would like to sort solely by the numeric portion of the string then @extramaster 's answer should serve you well.

function(a, b){
        var parts, textPartA, textPartB, numericPartA, numericPartB;

        parts = a.split('-');
        textPartA = parts[0];
        numericPartA = parseFloat(parts[1]);

        parts = b.split('-');
        textPartB = parts[0];
        numericPartB = parseFloat(parts[1]);

        //sort by text first
        if(textPartA < textPartB) {
            return -1;
        }
        if(textPartA > textPartB) {
            return 1;
        }

        //text parts are equal, now sort by the numeric parts
        if(numericPartA < numericPartB){
            return -1;
        }
        if(numericPartA > numericPartB){
            return 1;
        }

        return 0;
    }

@Jonny: A quick example

Try this code:

function (x, y) {
    x=x.myname;
    y=y.myname;

    var nameA = x.toLowerCase().split("-")[0],
        nameB = y.toLowerCase().split("-")[0]
    if (nameA < nameB) //sort string ascending
    return -1
    if (nameA > nameB) return 1
    var floatExtract = /(([1-9][0-9]*\.?[0-9]*)|(\.[0-9]+))([Ee][+-]?[0-9]+)?/;
    if (floatExtract.test(x) && floatExtract.test(y)) {
        x = x.match(floatExtract)[1];
        y = y.match(floatExtract)[1];
        if (!isNaN(parseFloat(x)) && !isNaN(parseFloat(y))) {
            x = parseInt(x);
            y = parseInt(y);
        }
        return ((x > y) ? 1 : ((x < y) ? -1 : 0));
    }
    return 0;
}

It splits your string and does a simple parison with the first portion [before the hyphen], then searches for a float inside of your string and does another sort on the list against that...

Demo | Source

Here is a similar solution on another page: Javascript not sorting DECIMAL numbers correctly

The idea is to sort by the string first then the number.

Ok I used rlemon's code sample and edited it to the following:

function(a, b) {
var parts = {
    a: a.myname.split(' - '),
    b: b.myname.split(' - ')
};
if (parts.a[0] == parts.b[0]) // strings are the same
    return parseFloat(parts.a[1]) - parseFloat(parts.b[1]); // sort by number
return parts.a[0] > parts.b[0] ? 1 : -1; // sort by string

}

本文标签: javascript sorting decimal numbers correctlyStack Overflow