简体   繁体   中英

custom sorting scientific notation using jQuery plugin dataTables

I'm trying to sort numbers like these:

<1E-8

0.000027

0.000061

0.0018

0.0094

<8.64e-12

0.049

'<' means that the true value is less than the number given.

Here is my "descent function," which I have a very high confidence in:

$.fn.dataTableExt.oSort['scientific-desc'] = function(a,b) {
                    var x = a.replace(/^[<>]/g,"");
                    var y = b.replace(/^[<>]/g,"");
                    x = parseFloat(x);
                    y = parseFloat(y);

                    return ((x < y) ? 1 : ((x > y) ? -1 : 0));
}

And I defined an "ascent function" similarly:

$.fn.dataTableExt.oSort['scientific-asc'] = function(a,b) {
                    var x = a.replace(/^[<>]/g,"");
                    var y = b.replace(/^[<>]/g,"");
                    x = parseFloat(x);
                    y = parseFloat(y);

                    return ((x < y) ? -1 : ((x > y) ? 1 : 0));
}

I've played with just about everything in the initialization code and with the above sorting functions but nothing seems to be able to get the numbers to sort correctly in the table. The numbers <1E-8 always tend to stay together and so do the ones with a lowercase 'e'.

The code to initialize the dataTable is as follows. It's probably worth noting that this is code is called inside of an AJAX call:

$.get('xyz.json',
    function(data) {
        // deal with json data 
        // get it ready for dataTable
        // ... 

    $('.table').dataTable( {
                    "sScrollY": "200px",
                    "aoColumns": [
                        null,
                        null,
                        {"bSortable": true, "sType": "scientific"},
                        {"bSortable": false}
                    ],
                    "aaSorting": [ [2,'asc'] ],
                    "bPaginate": false,
                    "bFilter": false,
                    "iDisplayLength": 5,
                    "bRetrieve": true,
                    "bDestroy": true
    } );
});

In your example, the numbers with '<' signs are next to each other in the sorted list.

var A= ['<1E-8', 0.000027, 0.000061, 0.0018, 0.0094, '<8.64e-12', 0.049];

A.sort(function(a, b){
    var a1= String(a).replace(/^(<|>)/, ''),
    b1= String(b).replace(/^(<|>)/, '');
    return a1-b1;
}).join('\n');

<8.64e-12
<1E-8
0.000027
0.000061
0.0018
0.0094
0.049

//To have a decending sort, just reverse it-

 A.sort(function(a, b){
    var a1= String(a).replace(/^(<|>)/, ''),
    b1= String(b).replace(/^(<|>)/, '');
    return a1-b1;
}).reverse().join('\n');


0.049
0.0094
0.0018
0.000061
0.000027
<1E-8
<8.64e-12

Serves me right for having "high confidence" in my sorting function. Quickly printing out a and b on the console revealed that the sorting functions were getting passed html entities

&lt;

and not "<".

Thanks to another stackoverflow thread :

varTitle = $('<div />').html("Chris&apos; corner").text();

Another way to do custom sorting in DataTables is to include something hidden in the table cell:

<tr>
  <td>Large<input type="hidden" value="3"></td>
</tr>
<tr>
  <td>Small<input type="hidden" value="1"></td>
</tr>
<tr>
  <td>Medium<input type="hidden" value="2"></td>
</tr>

And then sort by the hidden value instead of the displayed value:

// Tell DataTables to use this sort type always
$.fn.dataTableExt.aTypes.unshift(
   function () {
       return 'custom-sort';
   }
);


$.extend($.fn.dataTableExt.oSort, {
    // The selector
    "custom-sort-pre": function(a) {
        var sortValue = $(a).val();
        if (sortValue === undefined) {
            return a;
        }

        if (sortValue == 'NaN') {
            return NaN;
        }

        var floatValue = parseFloat(sortValue);
        if (isNaN(floatValue)) {
            return sortValue;
        }
        return floatValue;
    },

    // Asc sorting
   "custom-sort-asc": function (a, b) {
       if (isNaN(a) && !isNaN(b)) return 1;
       if (!isNaN(a) && isNaN(b)) return -1;
       if (isNaN(a) && isNaN(b)) return 0;

       if (a > b) return 1;
       if (a < b) return -1;
       return 0;
   },

    // Desc sorting
    "custom-sort-desc": function(a, b) {
        return $.fn.dataTableExt.oSort['custom-sort-asc'](a, b) * -1;
    }
});

This example will work on both strings and numbers.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM