Sorting files

Hello everyone. I drag a folder with numbered files into a playlist with sorting. Sorting occurs correctly if the files are numbered: 01, 02, …10, 11, etc.
But if the files are numbered: 1, 2, 3, … 11, 12, etc., then it turns out: 1, 10, 11…19, 2, 20, etc.
That is, sorting is done by the first character.
How can I sort files by two or three characters?
Here is the code:

File tempFile;
Array<File> dirFiles;
tempFile = File::getCurrentWorkingDirectory().getChildFile(filesNamesArray[i]).getLinkedTarget();
String audioFormats = audioFormatManager.getWildcardForAllFormats();
dirFiles = tempFile.findChildFiles (File::TypesOfFileToFind::findFiles, true, audioFormats);
dirFiles.sort();

Thank you in advance for your help.

use NaturalFileComparator

NaturalFileComparator sortNatural;
dirFiles.sort (sortNatural);

Unfortunately, it doesn’t work.

The ICU library has some very powerful, locale-aware collation support - Collation Examples | ICU Documentation

Maybe overkill, but if you can’t find anything else that works it will almost certainly do the job.

1 Like

Thank you. I will try.

You could use a bespoke comparator function.

I would get the filenames into a vector and sort it using the juce::String::getIntValue(). This function has the advantage, that it simply parses the string as long as the characters are numeric and ignores anything after that.

auto filesArray = documents.findChildFiles( juce::File::findFiles, false);
juce::Array<juce::String>  names;
for (const auto& file : filesArray)
    names.add (file.getFileName());

std::sort (names.begin(), names.end(), [](const auto& a, const auto& b)
{
    return a.getIntValue() < b.getIntValue();
});

juce::Array<juce::File> sorted;
for (const auto& name : names)
    sorted.add (documents.getChildFile (name);

Because std::Array has begin() and end() iterators, you can use the sort from the standard library.

It is a bit more complicated for a recursive search…

You might be able to compress the code, but this is the easiest version to read IMHO.

1 Like

Thank You. But for some reason sorting crashes debugging.

Hmm, there was at least one typo I edited now. I had a comma for < in the return of the sorting condition.

Can you try again and if the crash persists maybe post the error and/or the call stack?

Thanks Daniel! It all worked out. This is the final touch to my player.

1 Like

Looking at it again and after some coffee, let’s write it without the extra vectors:

auto filesArray = documents.findChildFiles (juce::File::findFiles, false);
std::sort (filesArray.begin(), filesArray.end(), [](const auto& a, const auto& b)
{
    return a.getFileName().getIntValue() < b.getFileName().getIntValue();
});
1 Like

This works great. Thank you very much!!!