0

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
    } );
});
gideonite
  • 1,211
  • 1
  • 8
  • 13

3 Answers3

0

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
kennebec
  • 102,654
  • 32
  • 106
  • 127
  • Are you saying that the regular expression needs a '|'? I don't think it matters whether you write ^[<>] or ^(<|>). The sorting functions seem to work. What's confusing me is that the dataTables plugin doesn't when I try to get it to use these sorting functions. – gideonite Apr 30 '12 at 03:13
0

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();
Community
  • 1
  • 1
gideonite
  • 1,211
  • 1
  • 8
  • 13
0

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.

Lasse Skindstad Ebert
  • 3,370
  • 2
  • 29
  • 28