Hi @Aza , I think the algorithm we used(by padding zero to the start of the string) to compare two strings can not handle this case well.
I do some research about how to sort file naturally and found https://blog.miigon.net/posts/how-to-sort-file-names-naturally/。I believe this is a better solution to sort filename. So can we introduce this algorithm to the project?
@Aza Yes, You are right, this algorithm need some change. Basic idea is to process the array after splitted to find if there is float number need to be combined. For example:
functionnatSort(arr){returnarr.map(v=>{// split string into number/ascii substringsletprocessedName=[]letstr=vfor(leti=0;i<str.length;i++){letisNum=Number.isInteger(Number(str[i]));letj;for(j=i+1;j<str.length;j++){if(Number.isInteger(Number(str[j]))!=isNum){break;}}processedName.push(isNum?Number(str.slice(i,j)):str.slice(i,j));i=j-1;}// combine float number if needletresult=[]for (leti=0;i<processedName.length;i++){if(processedName[i]=="."&&result.length>0&&Number.isInteger(result[result.length-1])&&(i+1)<processedName.length&&Number.isInteger(processedName[i+1])){result[result.length-1]=result[result.length-1]+"."+processedName[i+1]i=i+1}else{result.push(processedName[i])}}// end of combine float numberreturnresult;}).sort((a,b)=>{letlen=Math.min(a.length,b.length);for(leti=0;i<len;i++){if(a[i]!=b[i]){letisNumA=typeofa[i]==="number";letisNumB=typeofa[i]==='number';if(isNumA&&isNumB){returna[i]-b[i];}elseif(isNumA){return-1;}elseif(isNumB){return1;}else{returna[i]<b[i]?-1:1;}}}// in case of one string being a prefix of the otherreturna.length-b.length;}).map(v=>v.join(''));}letb=['2.png','2.5.png','1.5.png','1.png'];console.log(natSort(b).join(' -> '))// will output: '1.png -> 1.5.png -> 2.png -> 2.5.png'
This code is just for demo, we could use regex to simplify the procedure in the real project.
But, I don't think this is a perfect solution too. some corner case still fail. take ['2.png', '2.5.png','1.5.png', '1.png', '1.5.5.png'] for example, it will output '1.png -> 1.5.5.png -> 1.5.png -> 2.png -> 2.5.png'.
Actually natural sort is really tricky with too many corner case to consider, even the famous library natsort(https://pypi.org/project/natsort/) will fail with ['2.png', '2.5.png','1.5.png', '1.png', '1.5.5.png'].
My first idea was to keep the current algorithm to be honest. And just allow adding the numeric separators (it can be . or , depending on the language) limited to one (here)
The downside of my method is that it will only dort by prepending numbers but it will cover the most important use case (audio files).
Let's try with this algorithm though and see the results.