使用 Javascript 或 jQuery 按第一列对表格进行快速排序

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7558182/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-24 02:43:26  来源:igfitidea点击:

Sort a table fast by its first column with Javascript or jQuery

javascriptjqueryperformancesortinghtml-table

提问by Stefanvds

I have a table which is dynamically populated from FullCalendar. The problem is that FullCalendardoes not care about its original order.

我有一个从FullCalendar. 问题是FullCalendar不关心它的原始顺序。

The table looks like this:

该表如下所示:

<table id="caltbl">
   <thead>
       <tr> <th> </th>   <th> Date </th>   <th> hours </th>  ... </tr>
   </thead>
   <tbody>
       <tr> <td class="sortnr">1</td>   <td></td> ... </tr>
       <tr> <td class="sortnr">3</td>   <td></td> ... </tr>
       <tr> <td class="sortnr">2</td>   <td></td> ... </tr>
       <tr> <td class="sortnr">4</td>   <td></td> ... </tr>
   </tbody>
</table>

The first of each row contains the number on which the table should be sorted.

每行的第一行包含表应排序的编号。

I had this code to sort it:

我有这个代码来排序它:

    var rows = $('#caltbl > tbody').children('tr').detach();

    for (var counter = 1; counter<=rows.length; counter++) {
        $(rows).each(function(index) {
            if ($(this).find(".sortnr").text()==counter){
               $('#caltbl > tbody:last').append($(this));
            }
        });
    }

This works fine in Firefox but causes me a major headache in Internet Explorer because there are more than 500 items and it hangs. I could add a setTimeoutbut that would not fix the real problem. The sorting is slow. What is a faster way to sort this?

这在 Firefox 中运行良好,但在 Internet Explorer 中让我非常头疼,因为有 500 多个项目并且它挂起。我可以添加一个,setTimeout但这并不能解决真正的问题。排序很慢。对此进行排序的更快方法是什么?

Instead of having to start from the <table>html, as I said it gets populated dynamically so I have an Arraywhich contains the html. 1 item per <tr>(unsorted)

不必从<table>html开始,正如我所说,它是动态填充的,所以我有一个Array包含 html 的内容。每件 1 件<tr>(未分类)

回答by Rob W

Fiddle: http://jsfiddle.net/qNwDe/

小提琴http: //jsfiddle.net/qNwDe/

I've written an efficient, cross-browser method to sort the rows in your table. Multiple JQuery selectors in double loops are causing serious performance issues (as you've noticed), hence I've get rid of JQuery.

我编写了一种高效的跨浏览器方法来对表中的行进行排序。双循环中的多个 JQuery 选择器会导致严重的性能问题(如您所见),因此我摆脱了 JQuery。

An additional advantage of my function is that it doesn't mind missing index numbers. I'm currently referring to the first cell of each row, rather than getting the element by class name. If you want to refer by classname, I will alter my function:

我的函数的另一个优点是它不介意缺少索引号。我目前指的是每行的第一个单元格,而不是按类名获取元素。如果你想通过类名引用,我会改变我的功能:

function sortTable(){
    var tbl = document.getElementById("caltbl").tBodies[0];
    var store = [];
    for(var i=0, len=tbl.rows.length; i<len; i++){
        var row = tbl.rows[i];
        var sortnr = parseFloat(row.cells[0].textContent || row.cells[0].innerText);
        if(!isNaN(sortnr)) store.push([sortnr, row]);
    }
    store.sort(function(x,y){
        return x[0] - y[0];
    });
    for(var i=0, len=store.length; i<len; i++){
        tbl.appendChild(store[i][1]);
    }
    store = null;
}

Call sortTable()whenever you want to sort the table.

sortTable()每当您想对表格进行排序时调用。

回答by Blazemonger

Try an approach like this: http://jsfiddle.net/qh6JE/

尝试这样的方法:http: //jsfiddle.net/qh6JE/

var rows = $('#caltbl > tbody').children('tr').get(); // creates a JS array of DOM elements
rows.sort(function(a, b) {  // use a custom sort function
    var anum = parseInt($(a).find(".sortnr").text(), 10);
    var bnum = parseInt($(b).find(".sortnr").text(), 10);
    return anum-bnum;
});
for (var i = 0; i < rows.length; i++) {  // .append() will move them for you
    $('#caltbl > tbody').append(rows[i]);
}

回答by tsimbalar

I think there are way too many loops in your case. With 500 items, you would loop 500*500 = 250000 times . Not so many browsers would know how to do that.

我认为你的情况有太多的循环。对于 500 个项目,您将循环 500*500 = 250000 次。没有多少浏览器知道如何做到这一点。

I suggest using the native array.sort()method of javascript to do the sorting based on a custom "comparison function".

我建议使用array.sort()javascript的本机方法根据自定义的“比较函数”进行排序。

Here is how it could be done (and most probably it can be optimized) : http://jsfiddle.net/tsimbalar/Dw6QE/.

这是如何完成的(并且很可能可以对其进行优化):http: //jsfiddle.net/tsimbalar/Dw6QE/

The idea is to sort a list of rows comparing the sortNumber value ...

这个想法是对比较 sortNumber 值的行列表进行排序......

回答by Deano

Check out this http://square.github.com/crossfilter/the team at Square has used a clever bitmap index technique to allow filtering 5.3MB data in <30ms ... I am not sure if this helps, but it is a very interesting technique

看看这个http://square.github.com/crossfilter/Square 的团队使用了一种巧妙的位图索引技术来允许在 <30 毫秒内过滤 5.3MB 数据......我不确定这是否有帮助,但它是一个非常有趣的技术

回答by SharmaPattar

We can use jquery insead of javascript for the same thing answered by Rob W. It will not affect any performance issue like Multiple JQuery selectors in double loops.

我们可以将 jquery insead of javascript 用于 Rob W 回答的同一件事。它不会影响任何性能问题,例如双循环中的多个 JQuery 选择器。

var $tbody = $('table tbody');
            $tbody.find('tr').sort(function (a, b) {
                var tda = $(a).find('td:eq(' + ColumnIndex + ')').text(); // Use your wished column index
                var tdb = $(b).find('td:eq(' + ColumnIndex + ')').text(); // Use your wished column index
                // if a < b return 1
                return tda > tdb ? 1
                       // else if a > b return -1
                       : tda < tdb ? -1
                       // else they are equal - return 0    
                       : 0;
            }).appendTo($tbody);

Use < instead of >for descending.

使用 < 而不是 > 进行降序。

FIDDLE

小提琴