Last active
March 29, 2021 18:20
-
-
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.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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