I have been searching for this couldn't find it and tried implementing myself with regex but order is never right.
I need to apply to object with compare function, but let's say we have this array
test = [
"Oussama",
"Tarik R",
"Adam",
"Tarik2",
"12",
"13 x",
" ",
"@",
"",
"Zayn",
];
I want it to be sorted like ASCII sort but letters to be first like
test = [
"Adam",
"Tarik R",
"Tarik2", //the part after this doesn't matter if symbols first or numbers
"Zayn",
"12",
"13 x",
" ",
"@",
"",
];
What I have tried is testing with natural sort and regex but failed.
At first created 3 regex to compare with
//Regular name, could include a number or a char but doesn't start with it, ex Oussama, Oussama R, Oussama 2 rabat
const regName = /^[a-zA-Z].*[\s\.]*$/;
//Start with a number, not to be sorted first, ex 1 Oussama, 2Reda, 2# tarik
const regNumber =/^[0-9].*[\s\.]*/;
//Start with a symbol,ex @Oussama, 2@ Mohamed zenéée
const regSymbol = /^[ -!@#$%^&*()_+|~=`{}\[\]:";'<>?,.\/].*[\s\.]*/;
Then I found this solution, tested it, updated it and of course it didn't work for my case
var reN = /[^0-9]/g;
var reL = /[^a-zA-Z]/g;
function naturalCompare(a, b) {
var ax = [], bx = [];
a.replace(reN, function(_, $1, $2) { ax.push([$1 || Infinity, $2 || ""]) });
b.replace(reL, function(_, $1, $2) { bx.push([$1 || Infinity, $2 || ""]) });
while(ax.length && bx.length) {
var an = ax.shift();
var bn = bx.shift();
var nn = (an[0] - bn[0]) || an[1].localeCompare(bn[1]);
if(nn) return nn;
}
return ax.length - bx.length;
}