DataTables 对字符串而不是数字进行排序
Posted
技术标签:
【中文标题】DataTables 对字符串而不是数字进行排序【英文标题】:DataTables sorts strings instead of numeric 【发布时间】:2012-07-05 16:24:01 【问题描述】:我正在使用jquery.datatables 在数据表列中显示数字。数字被格式化为在千单位之间有空格(如123 456 789
)。不幸的是,这种数字格式会引发 string 排序而不是 number 排序(请参阅本问题末尾的屏幕截图)。
我已经确定:
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】:要对这种值进行排序,可以使用这个排序函数:
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
。
【讨论】:
太棒了!但是我怎么能强制 _fnSort() 对相关列使用这个排序函数呢? 这里是 DataTables 的作者 - 很好的答案 - 投了赞成票。我建议标记为正确/接受:-)。唯一的错字是 sType 作为大写的“T”:datatables.net/ref#sType。还值得指出的是,还有很多其他的排序插件(有些具有类型检测功能)-datatables.net/plug-ins/sorting 嗨。抱歉打错了,现已修正。 太棒了!今天下午我会试试这个,然后告诉你:) 好吧,我偶然发现了另一个问题:如何“设置我的列的 sType”。我可以在文档“如何使用 DataTables 插件排序函数(基于类型)”部分中看到 javascript 代码。如果我在我的 html 中定义了大量的 dataTable,我该如何使用这个 javascript 代码?理想情况下,我会想象像好的,经过大量搜索,我找到了替代解决方案。 dystroy 和 Allan Jardine 提出的解决方案当然更干净。但这意味着触摸 HTML 和在my case 中,触摸 HTML 会引发像下面这样一个棘手的消息框。
所以我的解决方案是触摸 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));
,
【讨论】:
【参考方案3】:对于正在阅读本文并希望获得数字之间空格的完整答案的任何人:
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
],
);
【讨论】:
【参考方案4】:在构建 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
,你会发现他们有一个函数可以确定每列值的类型并捕获格式
【讨论】:
以上是关于DataTables 对字符串而不是数字进行排序的主要内容,如果未能解决你的问题,请参考以下文章
DataTables 根据 TD 属性值对 html 表进行排序