Skip to content

Instantly share code, notes, and snippets.

@Miigon
Last active March 29, 2021 18:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Miigon/8e35396b5af98449a121c78e7d3b6ef4 to your computer and use it in GitHub Desktop.
Save Miigon/8e35396b5af98449a121c78e7d3b6ef4 to your computer and use it in GitHub Desktop.
natural sort algorithm for sorting file name in a more intuitive "human-friendly" way.
// natural sort algorithm in JavaScript by Miigon.
// 2021-03-30
//
// GitHub: https://github.com/miigon/
function natSort(arr){
return arr.map(v=>{ // split string into number/ascii substrings
let aux = []
let str = v
for(let i=0;i<str.length;i++) {
let isNum = Number.isInteger(Number(str[i]));
let j;
for(j=i+1;j<str.length;j++) {
if(Number.isInteger(Number(str[j]))!=isNum) {
break;
}
}
aux.push(isNum ? Number(str.slice(i,j)) : str.slice(i,j));
i=j-1;
}
// console.log(aux);
return aux;
}).sort((a,b) => {
let len = Math.min(a.length,b.length);
for(let i=0;i<len;i++) {
if(a[i]!=b[i]) {
let isNumA = Number.isInteger(a[i]);
let isNumB = Number.isInteger(b[i]);
if(isNumA && isNumB) {
return a[i]-b[i];
} else if(isNumA) {
return -1;
} else if(isNumB) {
return 1;
} else {
return a[i]<b[i] ? -1 : 1 ;
}
}
}
// in case of one string being a prefix of the other
return a.length - b.length;
}).map(v => v.join(''));
}
let a = ['a2','a1b10z','b1a2','a1b10','a33','7','a3','a22','a1b2','abbbb','a1b1','aaaaa','a10','a1','10'];
console.log(natSort(a).join('\n'))
/*
7
10
a1
a1b1
a1b2
a1b10
a1b10z
a2
a3
a10
a22
a33
aaaaa
abbbb
b1a2
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment