Get files from directory sorted by name
Dr.No
jckj33 at gmail.com
Thu Apr 26 16:58:46 UTC 2018
On Wednesday, 25 April 2018 at 18:06:07 UTC, Jonathan M Davis
wrote:
> On Wednesday, April 25, 2018 17:34:41 Dr.No via
> Digitalmars-d-learn wrote:
>> Is there something implemented already to get the files from
>> directory by name using D or I'm on my own and I have to write
>> it myself? I didn't find how do that with dirEntries()
>
> There is nothing in the standard library for doing it, though
> maybe someone has something on code.dlang.org. However, the
> underlying OS API doesn't exactly conform well to that
> particular use case. AFAIK, given how the C APIs work, the only
> option is to get the list of files and then sort it, which
> could be done easily enough with dirEntries. Something as
> simple as
>
> auto files = dirEntries(dir, SpanMode.shallow).array();
> sort!((a, b) => a.name < b.name)(files);
>
> would give you a sorted DirEntry[] of all of the directories
> and files directly in the directory. SpanMode.depth or
> SpanMode.breadth could be used instead if you want
> sub-directories, and std.algorithm.iteration.filter could be
> used if you want to do something like filter out directories.
> std.algorithm.iteration.map could be used if you just want the
> file names. So, if you wanted just the names, you could do
>
> auto files = dirEntries(dir, SpanMode.shallow).map!(a =>
> a.name)().array();
> sort(files);
>
> though you'd need to use std.path.baseName if you didn't want
> the full path
> - e.g. map!(a => a.name.baseName)(). If you wanted just files,
> you could do
> something like
>
> auto files = dirEntries(dir, SpanMode.shallow).
> filter!(a => a.isFile()).array();
> sort!((a, b) => a.name < b.name)(files);
>
> or
>
> auto files = dirEntries(dir, SpanMode.shallow).
> filter!(a => a.isFile()).map!(a => a.name).array();
> sort(files);
>
> Exactly which combination of functions you use depends on what
> you want for the end result. But the key thing is that you use
> std.array.array to convert the forward range into a dynamic
> array so that std.algorithm.sorting.sort can sort it (since it
> requires a random-access range). I really don't think that
> you're going to find any other way to do this other than
> someone who has written a function that just ends up doing the
> same thing by wrapping a call to dirEntries or the underlying C
> API.
>
> - Jonathan M Davis
I have had just called sort, to later realize the sort wasn't in
the way humans expect (which is the way Windows Explorer does) so
I eventually reached
https://blog.codinghorror.com/sorting-for-humans-natural-sort-order/ but I failed to call StrCmpLogicalW() from core.sys.windows.shlwapi or link on my own:
pragma(lib, "Shlwapi.lib")
extern(Windows) int StrCmpLogicalW(
PCWSTR psz1,
PCWSTR psz2
);
but I got links error so I went to implement StrCmpLogicalW() on
my own and sorted like this:
auto files = dirEntries(inputDir, SpanMode.shallow).array();
// natural sort
sort!((a, b) => StrCmpLogical(a, b) < 0)(files);
which resulted in the files in same way as Windows
Explorer/Natural sort.
More information about the Digitalmars-d-learn
mailing list