I am trying to sort a list of objects by a string which is the filename for a song, sometimes the filename includes numbers and letters, but every sorting method I've tried does not sort the filenames in an order you you would expect, such as in my example below, the expected output is:
Track 1
Track 2
Track 10
but it gets sorted incorrectly as:
Track 1
Track 10
Track 2
var inputFiles=[
{
'name':'Track 1.wav'
},
{
'name':'Track 2.wav'
},
{
'name':'Track 10.wav'
},
]
console.log('sort audio files by title: ', inputFiles)
let sortedAudio = inputFiles.sort(function(a, b) {
var textA = a['name'].toUpperCase();
var textB = b['name'].toUpperCase();
return (textA < textB) ? -1 : (textA > textB) ? 1 : 0;
});
console.log('sortedAudio=',sortedAudio)
CodePudding user response:
Comparing strings with textA < textB
will give you results according to the lexiographic order of each character - in which case 1 10 2
is the correct ordering. Compare the differences of the numbers instead of doing a string comparison, for which you'll have to extract only the numeric portion of the string. -
can be used, which will convert each side to a number first.
var inputFiles = [{
'name': 'Track 1.wav'
},
{
'name': 'Track 2.wav'
},
{
'name': 'Track 10.wav'
},
]
console.log('sort audio files by title: ', inputFiles);
inputFiles.sort((a, b) => a.name.match(/\d /)[0] - b.name.match(/\d /)[0]);
console.log('sortedAudio=', inputFiles);
CodePudding user response:
String#localeCompare
can handle numbers for you if you set the numeric
option. Remember to check if the current browser supports options
and fall back to an approach like CertainPerformance's answer if it does not.
var inputFiles = [
{ 'name': 'Track 10.wav' },
{ 'name': 'Track 1.wav' },
{ 'name': 'Track 2.wav' },
{ 'name': 'Track 7.wav' },
{ 'name': 'Unknown Track.wav' },
{ 'name': 'Track 4.wav' },
{ 'name': 'Track 100.wav' },
{ 'name': 'Track 13.wav' },
{ 'name': 'Track 20.wav' },
{ 'name': 'Unknown Track.wav' }
];
const sortedAudio = inputFiles.sort((a,b) =>
a.name.localeCompare(b.name, undefined, { numeric: true }));
console.log('sortedAudio: ', sortedAudio);