DataTables对字符串进行排序而不是数字

时间:2012-07-05 09:21:44

标签: jquery sorting datatables

我使用jquery.datatables在datatables列中显示数字。数字被格式化为具有千位单位之间的空格(如123 456 789)。不幸的是,这个数字格式化了 string 排序而不是数字排序(请参阅本问题末尾的屏幕截图)。

我已经确定:

  • function _fnSort(oSettings, bApplyClasses) {是排序的核心功能。
  • 在此函数中,使用动态函数排序方法(如果if (!window.runtime) {为真,则执行该方法)
  • 使用的字符串排序函数是以下两个函数。

    /*
    * text sorting
    */
    "string-asc": function(a, b) {
        var x = a.toLowerCase();
        var y = b.toLowerCase();
        return ((x < y) ? -1 : ((x > y) ? 1 : 0));
    },
    
    "string-desc": function(a, b) {
        var x = a.toLowerCase();
        var y = b.toLowerCase();
        return ((x < y) ? 1 : ((x > y) ? -1 : 0));
    },
    

我对javascript的了解非常差,这里最好的方法是什么?

  1. 调整字符串排序功能以检测数千格式的情况,然后进行比较(我猜这在大数据集上会相当慢)。
  2. 提供专用于数千格式的数字排序功能?在这种情况下
    • 你会怎么编码?
    • 如何指示核心排序功能,使用这种特殊的数字排序功能?
  3. 以下是现在的排序:

    enter image description here

4 个答案:

答案 0 :(得分:10)

要对此类值进行排序,您可以使用此排序功能:

var sortFunction=function(a, b)​{
    var ia = parseInt(a.split(' ').join(''), 10);
    var ib = parseInt(b.split(' ').join(''), 10);
    return ia-ib;
};

测试:

var data = ['3 333', '100 333', '22 000', '1 333'];
console.log(data.sort(sortFunction));

使用合理数量的值,这将足够快。如果您没有检测到性能问题,则不应尝试丰富数据。

编辑:

事实上,the documentation提出了一个适当的(类似的)排序函数:

jQuery.extend( jQuery.fn.dataTableExt.oSort, {
    "formatted_numbers-pre": function ( a ) {
        a = (a==="-") ? 0 : a.replace( /[^\d\-\.]/g, "" );
        return parseFloat( a );
    },

    "formatted_numbers-asc": function ( a, b ) {
        return a - b;
    },

    "formatted_numbers-desc": function ( a, b ) {
        return b - a;
    }
} );

添加此扩展程序后,您只需设置列的sType

答案 1 :(得分:0)

好的,经过大量搜索后,我找到了另一种解决方案。 dystroy Allan Jardine 提出的解决方案当然更清晰。但这意味着触摸HTML并在my case中触及HTML激发的棘手消息框,如下所示。

enter image description here

所以我的解决方案就是触摸javascript字符串排序算法,在数字和文本情况之间切换。我希望通过使用像isDigit(sa.charAt[0])这样的东西可以更清洁但是尽管我尝试了所有这些东西它都不起作用。至少这个解决方案有效,并不意味着任何明显的性能成本:

    /*
    * text + integer sorting
    */
    "string-asc": function(a, b) {
       var sa = a.toString();
       if(sa.length > 0) {
          // Don't know why, isDigit(sa.charAt[0]) doesn't work??
          var ca = sa.substring(0,1);
          if(ca === "0" || ca === "1" || ca === "2" || ca === "3" || ca === "4" || ca === "5" || ca === "6" || ca === "7" || ca === "8" || ca === "9") {
             var x1 = parseInt(a.split(' ').join(''), 10);
             var y1 = parseInt(b.split(' ').join(''), 10);
             return x1 - y1;
          }
       }
       var x = a.toLowerCase();
       var y = b.toLowerCase();
       return ((x < y) ? -1 : ((x > y) ? 1 : 0));
    },

    "string-desc": function(a, b) {
        var sa = a.toString();
        if(sa.length > 0) {
           var ca = sa.substring(0,1);
           if(ca === "0" || ca === "1" || ca === "2" || ca === "3" || ca === "4" || ca === "5" || ca === "6" || ca === "7" || ca === "8" || ca === "9") {
              var x1 = parseInt(a.split(' ').join(''), 10);
              var y1 = parseInt(b.split(' ').join(''), 10);
              return y1 - x1;
           }
        }
        var x = a.toLowerCase();
        var y = b.toLowerCase();
        return ((x < y) ? 1 : ((x > y) ? -1 : 0));
    },

答案 2 :(得分:0)

对于正在阅读此内容且希望得到数字之间空格的完整答案的任何人:

  jQuery.extend( jQuery.fn.dataTableExt.oSort, {
      "formatted_numbers-pre": function ( a ) {
        a = (a===" ") ? 0 : a.replace( /[^\d\-\.]/g, "" );
        return parseFloat( a );
      },

      "formatted_numbers-asc": function ( a, b ) {
        return a - b;
      },

      "formatted_numbers-desc": function ( a, b ) {
        return b - a;
      }
  } );

    $('.myTable').DataTable({
      "columnDefs": [
        { "type": "formatted_numbers", "targets": 4 }
      ],
    });
  }

答案 3 :(得分:0)

在构建DataTable时,只需设置小数点,如下所示:

var main_table = $('#main_list').DataTable({
    ajax: {
        url: "/api/your/data",
        dataSrc: ''
    },
    columns: [
        { data: "Col1" },
        { data: "Col2" },
        { data: "Col3" },
        { data: "Col4" }
    ],
    language: {
        /* -----> */ "decimal": ",", // <---------
        "emptyTable": "Keine Daten in der Tabelle verfügbar",
        "info": "Anzeigen von _START_ bis _END_ von _TOTAL_ Einträgen",
        "infoEmpty": "Anzeigen von 0 bis 0 von 0 Einträgen",
        "infoFiltered": "(filtriert von_MAX_ Gesamteinträge)",
        "infoPostFix": "",
        /* -----> */ "thousands": ".", // <---------
        "lengthMenu": "_MENU_ Einträge anzeigen",
        "loadingRecords": "Laden...",
        "processing": "Verarbeitung...",
        "search": "Suche:",
        "zeroRecords": "Keine passenden Datensätze gefunden",
        "paginate": {
            "first": "Erste",
            "last": "Letzte",
            "next": "Nächste",
            "previous": "Vorherige"
        },
        "aria": {
            "sortAscending": ": aufsteigend sortieren",
            "sortDescending": ": absteigend sortieren"
        }
    },
    columnDefs: [
        {//set german formatting

            render: function (data, type, row) {
                return formatDE(data,2);
            },
            targets: [2, 4, 5]
        },
        {

            render: function (data, type, row) {
                return formatDE(data,0);
            },
            targets: [3]
        }
    ],
    pageLength: 50});

如果你深入研究jquery.dataTables.js,你会发现它们有一个确定每个列值的类型并捕捉格式的函数