Complex Sort of Field "String - Number - String"

Javascript : natural sort of alphanumerical strings

This is now possible in modern browsers using localeCompare. By passing the numeric: true option, it will smartly recognize numbers. You can do case-insensitive using sensitivity: 'base'. Tested in Chrome, Firefox, and IE11.

Here's an example. It returns 1, meaning 10 goes after 2:

'10'.localeCompare('2', undefined, {numeric: true, sensitivity: 'base'})

For performance when sorting large numbers of strings, the article says:

When comparing large numbers of strings, such as in sorting large arrays, it is better to create an Intl.Collator object and use the function provided by its compare property. Docs link

var collator = new Intl.Collator(undefined, {numeric: true, sensitivity: 'base'});
var myArray = ['1_Document', '11_Document', '2_Document'];
console.log(myArray.sort(collator.compare));

Sort an array which contains number and strings

It seems you have done most of the work in your second attempt.
All I have done here is used Array.concat to join the sorted results of number and char together.

var arr = [9, 5, '2', 'ab', '3', -1] // to be sortedvar number = [];var char = [];arr.forEach(a => {  if (typeof a == 'number') number.push(a);  else char.push(a);})

var sorted = number.sort().concat(char.sort());console.log(sorted)

Sort on a string that may contain a number

The Alphanum Algorithm

From the website

"People sort strings with numbers differently than software. Most sorting algorithms compare ASCII values, which produces an ordering that is inconsistent with human logic. Here's how to fix it."

Edit: Here's a link to the Java Comparator Implementation from that site.

NSFetchedResultsController - sort as a number but string field

var sortDescriptor = NSSortDescriptor(key: "title", ascending: true,
selector: #selector(NSString.localizedStandardCompare))
fetchRequest.sortDescriptors = [sortDescriptor]

Sort array of objects by string property value

It's easy enough to write your own comparison function:

function compare( a, b ) {
if ( a.last_nom < b.last_nom ){
return -1;
}
if ( a.last_nom > b.last_nom ){
return 1;
}
return 0;
}

objs.sort( compare );

Or inline (c/o Marco Demaio):

objs.sort((a,b) => (a.last_nom > b.last_nom) ? 1 : ((b.last_nom > a.last_nom) ? -1 : 0))

Or simplified for numeric (c/o Andre Figueiredo):

objs.sort((a,b) => a.last_nom - b.last_nom); // b - a for reverse sort

Javascript sort string or number

The problem might be that you're calling the jQuery constructor a bunch of times and doing heavy operations on it (e.g. using .find() with complex selectors). Therefore, your function is just slow and that's probably the issue.

The good news is that JavaScript has a native implementation of QuickSort (a very fast sorting function) that will probably take care of your needs. When combined with a reduction in expensive calls, your code should end up being enormously more efficient. I'd change your code to look like this:

var sortByField = function(field, mode) {
var numExp = /^-?\d*\.?\d+$/;
var $rows = $(".data tr:not(.hdr)"), $table = $(".data");
$rows.each(function () {
this.fieldVal = $(this).find("td:eq("+field+")").text();
if(numExp.test(this.fieldVal)) { //if field is numeric, convert it to a number
this.fieldVal = +this.fieldVal;
}
}).sort(function (a, b) {
if (mode === 1) {
return (a.fieldVal > b.fieldVal) ? -1 : 1;
}
return (a.fieldVal < b.fieldVal) ? -1 : 1;
}).detach().each(function () {
$(this).appendTo($table);
});
};

This won't work well with multiple tables on one page (because it assumes everything is on the same table). So if you want to do that, you should pass in the table or table selector as a parameter. But that's an easy fix to make. You can see my solution in action here:

http://jsfiddle.net/r8wtK/ (updated)

It should be far more efficient than your code and should reduce "freezing" by quite a bit (ore even entirely).

UPDATE:

The OP noted that some fields may contain strings. Doing a string comparison on numbers is bad because it returns a lexicographical ordering (e.g. "10" < "2"). So I added a test to see if the data appear to be numeric before doing the sort.

Sorting numbers cast as strings in react

parseInt() won't work on strings with commas in them, you'll have to remove them manually when you sort:

customSort: (a, b) => parseInt(a.salary.replace(/,/g, '')) - parseInt(b.salary.replace(/,/g, ''))


Related Topics



Leave a reply



Submit