Javascript排序字符串或数字

Javascript sort string or number

本文关键字:数字 字符串 排序 Javascript      更新时间:2023-09-26

编辑:Pete提供了一个非常好的解决方案,当字段包含数字时可以工作,但我也需要能够对字符串进行排序-有什么想法吗

我正在尝试编写一种javascript排序算法,它将根据单击的列对表进行排序-我知道这是半重新发明轮子,但设计太复杂了,我无法尝试插入其他插件等。

有些列是文本,有些列是数字。

单击列调用:sort(X,Y)。X是列编号,因此我们知道要比较哪些单元格进行排序。Y是模式,即升序或降序。

分拣功能的代码为:

function sort(field, mode) {
var tabrows = 0;
$(".data tr").each(function() { if($(this).hasClass("hdr")) { } else {tabrows++;} });   
var swapped;
do {
        swapped = false;
        for (var i=0;i< tabrows; i++) {
            var j = i + 3;
            var k = i + 4;  
            var row1 = $(".data tr:nth-child("+j+")");
            var row2 = $(".data tr:nth-child("+k+")");
            var field1 = row1.find("td:eq("+field+")").text();      
            var field2 = row2.find("td:eq("+field+")").text();
            if(shouldswap(field1, field2, mode)) {
                swaprows(row1, row2);
                swapped = true;
            }
        }
    } while (swapped);
}

shouldswap函数如下:

function shouldswap(field1, field2,mode) {

    if(field1 > field2) {
            if(mode==1) {   
                return true;
            } else {
                return false;
            }   
    }
    return false;
}

swaprows功能代码:

function swaprows(row1, row2) {
      row2.insertBefore(row1);
}

有人能理解为什么这会导致浏览器冻结/锁定吗。我已经做了很长一段时间了,所以我想一双新的眼睛可能会指出一些愚蠢的事情!感谢您的帮助:)

问题可能是您多次调用jQuery构造函数并对其执行繁重的操作(例如,使用带有复杂选择器的.find())。因此,你的功能很慢,这可能就是问题所在。

好消息是,JavaScript有一个QuickSort(一个非常快速的排序函数)的本地实现,它可能会满足您的需求。当与减少昂贵调用相结合时,代码的效率应该会大大提高。我会把你的代码改成这样:

var sortByField = function(field, mode) {
    var numExp = /^-?'d*'.?'d+$/;
    var $rows = $(".data tr:not(.hdr)"), $table = $(".data");
    $rows.each(function () {
        this.fieldVal = $(this).find("td:eq("+field+")").text();
        if(numExp.test(this.fieldVal)) { //if field is numeric, convert it to a number
            this.fieldVal = +this.fieldVal;
        }
    }).sort(function (a, b) {
        if (mode === 1) {
            return (a.fieldVal > b.fieldVal) ? -1 : 1;    
        }    
        return (a.fieldVal < b.fieldVal) ? -1 : 1;
    }).detach().each(function () {
        $(this).appendTo($table);
    });
};

对于一个页面上的多个表,这不会很好地工作(因为它假设所有内容都在同一个表上)。因此,如果您想这样做,您应该将表或表选择器作为参数传入。但这是一个很容易解决的问题。你可以在这里看到我的解决方案:

http://jsfiddle.net/r8wtK/(更新)

它应该比您的代码效率高得多,并且应该大大减少"冻结"(甚至完全减少)。

更新:

OP指出,有些字段可能包含字符串。对数字进行字符串比较是不好的,因为它返回字典排序(例如"10" < "2")。因此,在进行排序之前,我添加了一个测试来查看数据是否显示为数字。

可能是为了获得行索引而向i添加了3和4吗?因此,当i到达(tabrows-1)时,它似乎将尝试访问索引为(tabrows+2)(tabrows+3)的行。如果我正确理解你的逻辑,这些都是越界的,所以row1row2field1field2将为空。因此,如果您在mode==1中,我认为这将使您的算法尝试交换这两个不存在的行,并不断比较无穷大。这有道理吗,还是我误解了你的逻辑?

如果是这样的话,我认为你只需要将for循环更改为:

for (var i=0;i< tabrows-4; i++) {
     // your code
}

不管怎样,在j上加3,在k上加4的目的是什么?您是否在顶部有3行数据不想进行比较?