Thread overview | |||||||||
---|---|---|---|---|---|---|---|---|---|
|
April 25, 2018 Get files from directory sorted by name | ||||
---|---|---|---|---|
| ||||
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() |
April 25, 2018 Re: Get files from directory sorted by name | ||||
---|---|---|---|---|
| ||||
Posted in reply to Dr.No | 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
|
April 25, 2018 Re: Get files from directory sorted by name | ||||
---|---|---|---|---|
| ||||
Posted in reply to Dr.No | On Wednesday, 25 April 2018 at 17:34:41 UTC, Dr.No 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()
I want to add that sorting can be done, if you just call std.algorithm.sort you'll find that file names with numbers in them will be sorted as a well strings.
Newfile1.txt
Newfile10.txt
Newfile2.txt
|
April 26, 2018 Re: Get files from directory sorted by name | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jonathan M Davis | 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. |
April 26, 2018 Re: Get files from directory sorted by name | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jesse Phillips | On Wednesday, 25 April 2018 at 19:25:11 UTC, Jesse Phillips wrote:
> On Wednesday, 25 April 2018 at 17:34:41 UTC, Dr.No 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()
>
> I want to add that sorting can be done, if you just call std.algorithm.sort you'll find that file names with numbers in them will be sorted as a well strings.
>
> Newfile1.txt
> Newfile10.txt
> Newfile2.txt
I've had realized that then implemented natural sort
|
April 27, 2018 Re: Get files from directory sorted by name | ||||
---|---|---|---|---|
| ||||
Posted in reply to Dr.No | On Thursday, 26 April 2018 at 16:59:45 UTC, Dr.No wrote: > On Wednesday, 25 April 2018 at 19:25:11 UTC, Jesse Phillips wrote: >> On Wednesday, 25 April 2018 at 17:34:41 UTC, Dr.No 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() >> >> I want to add that sorting can be done, if you just call std.algorithm.sort you'll find that file names with numbers in them will be sorted as a well strings. >> >> Newfile1.txt >> Newfile10.txt >> Newfile2.txt > > I've had realized that then implemented natural sort Thats what it was called. Looks like Rosetta Code has an implementation. https://rosettacode.org/wiki/Natural_sorting#D |
April 27, 2018 Re: Get files from directory sorted by name | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jesse Phillips | On Friday, 27 April 2018 at 14:48:00 UTC, Jesse Phillips wrote:
> On Thursday, 26 April 2018 at 16:59:45 UTC, Dr.No wrote:
>> On Wednesday, 25 April 2018 at 19:25:11 UTC, Jesse Phillips wrote:
>>> On Wednesday, 25 April 2018 at 17:34:41 UTC, Dr.No 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()
>>>
>>> I want to add that sorting can be done, if you just call std.algorithm.sort you'll find that file names with numbers in them will be sorted as a well strings.
>>>
>>> Newfile1.txt
>>> Newfile10.txt
>>> Newfile2.txt
>>
>> I've had realized that then implemented natural sort
>
> Thats what it was called. Looks like Rosetta Code has an implementation.
>
> https://rosettacode.org/wiki/Natural_sorting#D
I've tried here and that implmentation doesn't yield same result as Windows Explorer...
|
Copyright © 1999-2021 by the D Language Foundation