javascript正确排序十进制数

javascript sorting decimal numbers correctly

好的,我有一段代码,它按字母顺序排列名字。

然而,代码不能按我想要的方式处理小数。

它按以下方式对名称排序(obv i希望它以数字形式递增):

它会命令它:

  • 苹果-1.0051
  • 苹果-1.1071
  • 苹果-11.1592
  • 苹果-12.0692
  • 苹果-12.1717
  • apple-2.0186<<这应该在"apple-1.1071"之后。
  • 苹果-21.1407
  • 苹果-22.089
  • 苹果-23.069
  • 香蕉-1.0051
  • 香蕉-1.1071
  • 香蕉-11.1592
  • 香蕉-12.0692
  • 香蕉-12.1717
  • 香蕉-2.0186<<这明显应该在"香蕉-1.1071"之后。
  • 香蕉-21.1407
  • 香蕉-22.089
  • 香蕉-23.069

这是我使用的代码。我不完全理解代码,因为它是我一直使用的一个片段。

1
2
3
4
5
6
7
8
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)
    }

当做,强尼


演示,下面是源代码+小解释:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
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"
]

首先,函数将术语拆分为文本和数字部分-如果文本是偶数,则只对数值的parsefloat值排序-否则,它将首先按字符串值排序。


就像@steve wellens在他的评论中建议的那样,我修改了您现有的代码片段,先比较文本部分,然后在出现平局的情况下,通过将其转换为floats,比较字符串的数字部分。如果您只想按字符串的数字部分排序,那么@extramaster的答案应该很适合您。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
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;
    }

@乔尼:一个简单的例子


尝试此代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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;
}

它拆分字符串并与第一部分(连字符之前)进行简单比较,然后在字符串内部搜索一个浮点值,然后在列表中对其进行另一种排序…

演示来源


另一页上也有类似的解决方案:javascript未正确排序十进制数

其思想是先按字符串排序,然后按数字排序。


好的,我使用了rlemon的代码示例,并将其编辑为以下内容:

1
2
3
4
5
6
7
8
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

}