Javascript排序字符串或数字

时间:2012-09-12 16:18:20

标签: javascript jquery sorting

编辑: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);
}

任何人都可以看到为什么这会导致浏览器冻结/锁定。我已经在这方面工作了一段时间,所以我觉得一副新鲜的眼睛可能会指出一些愚蠢的东西!任何帮助表示赞赏:)

2 个答案:

答案 0 :(得分:1)

问题可能在于您多次调用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")。所以我在进行排序之前添加了一个测试,以查看数据是否显示为数字。

答案 1 :(得分:0)

是否可以将{3}添加到i以获取行索引?因此,当i到达(tabrows-1)时,它似乎会尝试访问索引为(tabrows+2)(tabrows+3)的行。如果我正确理解您的逻辑,那么这些逻辑已超出范围,因此row1row2field1field2将为空。因此,如果您在mode==1,我认为这将使您的算法尝试交换这两个不存在的行并继续比较无穷大。这是否有意义,或者我误解了你的逻辑?

如果是这种情况,我认为您只需将for循环更改为:

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

无论如何,将3添加到j和4到k的目的是什么?顶部有3行数据,您不想比较吗?