How can I customize this already configured jQuery sorting solution?

I found the following solution to add sorting capabilities to jQuery (ref: jQuery sort () ), I changed my solution to sort lines of unknown length. It works well, however, as you might have noticed from the function name: it sorts out acscending :-).

jQuery.fn.sort = function() {  
    return this.pushStack( [].sort.apply( this, arguments ), []);  
};  

function sortStringAscending(a,b){
    var h1 = a.innerHTML;
    var h2 = b.innerHTML;
    var c = 0;
    var str1 = null,
    var str2 = null;

    while(str1 == str2 && (c < h1.length && c < h2.length)) {
        str1 = h1.substring(c,c+1).toLowerCase().charCodeAt(0);
        str2 = h2.substring(c,c+1).toLowerCase().charCodeAt(0);

        if(str1 > str2) {
            r = 1;
        } else if(str2 > str1) {
            r = -1;
        }

        c += 1;
    }
    return r;  
};  

      

The function is used like this:

$('ol li').sort(sortStringAscending).appendTo('ol');

      

Can this code be modified to make the following possible:

$('ol li').sort(sortString, 0).appendTo('ol');  //0 for descending
$('ol li').sort(sortString, 1).appendTo('ol');  //1 for ascending

      

+1


a source to share


5 answers


You won't be able to easily get the extra argument in the array sort function that jQuery.fn.sort uses.

It will be easier to use two separate functions, one for ascending and one for descending, but keep the actual comparison in the third function.

function sortStringAscending(a,b) {
    return sortString(a,b,1);
};
function sortStringDescending(a,b) {
    return sortString(a,b,-1);
};
function sortString(a,b,direction) {
   var h1 = a.innerHTML.toLowerCase();
   var h2 = b.innerHTML.toLowerCase();

   if(h1 > h2) {
      r = 1*direction;
   } else if(h2 > h1) {
      r = -1*direction;
   }
   return r;  
};

      



Also note that you can simply compare two strings, there is no need to compare them character by character unless you want unpredictable sort ordering for items like "abc" and "abcd".

Then you should be able to do

$('ol li').sort(sortStringAscending).appendTo('ol');
$('ol li').sort(sortStringDescending).appendTo('ol');

      

+3


a source


Change this:

if(str1 > str2) {
    r = 1;
} else if(str2 > str1) {
    r = -1;
}

      

:

if(str1 > str2) {
    r = -1;
} else if(str2 > str1) {
    r = 1;
}

      



will replace the sort order.


EDIT:

Because of the way the Javascript array.sort (callback) function works, it's not easy to add a third parameter to respond to the call, I suggest using two separate functions mySortAsc and mySortDesc, which in turn can call the third function and pass any parameters ...

0


a source


This will do what you asked: (use the parameter to define the sort order)

function sortString(a,b,direction){
var d = (direction?1:-1);
var h1 = a.html();
var h2 = b.html();
var c = 0;
var str1 = null,
var str2 = null;

while(str1 == str2 && (c < h1.length && c < h2.length)) {
    str1 = h1.substring(c,c+1).toLowerCase().charCodeAt(0);
    str2 = h2.substring(c,c+1).toLowerCase().charCodeAt(0);

    if(str1 > str2) {
        r = 1*d;
    } else if(str2 > str1) {
        r = -1*d;
    }

    c += 1;
}
return r;  

      

};

0


a source


You might be able to use closure. Although the javascript array sort method expects a 2 parameters function, you can inject other information into the scope of the callback function by doing something like:

function BiSort(direction)
{
    return  function( a, b )
            {
                var d = ( direction ? 1 : -1 ) ;

                return ( a > b ? 1 : b > a ? -1 : 0 ) * d ; 
            }
}

      

The BiSort function returns a new function that has access to the parameter list of external functions. Now you can do this:

var a = ["ant", "goat", "bat", "zebra", "yak"] ;

a.sort(BiSort(true));  // sorts ascending

a.sort(BiSort(false)); // sort descending

      

0


a source


I know this is old, but for future reference, I would make 2 functions for asc / desc and then make a var dot one or the other based on what you need, then pass that var to array.sort ()

function SortAsc(a, b){
}

function SortDesc(a, b){
}

var sortOrder

// if asc button clicked
sortOrder = SortAsc;

// if desc button clicked
sortOrder = SortDesc;



$('ol li').sort(sortOrder);

      

0


a source







All Articles