www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Natural sorted list of files

reply Dmitry <dmitry indiedev.ru> writes:
Hi. I'm need get list of files in the directory, with natural 
sort, like:
file_2
file_8
file_10
file_11
file_20
file_100
etc.

Found this https://rosettacode.org/wiki/Natural_sorting#D
but there is error on ".groupBy!isDigit" (Error: no property 
'groupBy' for type 'string').

with deleted line it works, but order is incorrect, like:
file_1
file_10
file_11
file_100
file_2
file_20
etc.

How can I do this?
Feb 06
next sibling parent reply Jonathan M Davis via Digitalmars-d-learn writes:
On Monday, February 06, 2017 16:43:45 Dmitry via Digitalmars-d-learn wrote:
 Hi. I'm need get list of files in the directory, with natural
 sort, like:
 file_2
 file_8
 file_10
 file_11
 file_20
 file_100
 etc.

 Found this https://rosettacode.org/wiki/Natural_sorting#D
 but there is error on ".groupBy!isDigit" (Error: no property
 'groupBy' for type 'string').

 with deleted line it works, but order is incorrect, like:
 file_1
 file_10
 file_11
 file_100
 file_2
 file_20
 etc.

 How can I do this?
You have to import std.range to use groupBy. - Jonathan M Davis
Feb 06
parent reply Dmitry <dmitry indiedev.ru> writes:
On Monday, 6 February 2017 at 17:35:02 UTC, Jonathan M Davis 
wrote:
 You have to import std.range to use groupBy.
Of course, "import std.range" already done. I tested it also with full rosetta's code: import std.stdio, std.string, std.algorithm, std.array, std.conv, std.ascii, std.range; string[] naturalSort(string[] arr) /*pure safe*/ { static struct Part { string s; int opCmp(in ref Part other) const pure { return (s[0].isDigit && other.s[0].isDigit) ? cmp([s.to!ulong], [other.s.to!ulong]) : cmp(s, other.s); } } static mapper(in string txt) /*pure nothrow safe*/ { auto r = txt .strip .tr(whitespace, " ", "s") .toLower .groupBy!isDigit .map!(p => Part(p.text)) .array; return (r.length > 1 && r[0].s == "the") ? r.dropOne : r; } return arr.schwartzSort!mapper.release; } void main() /* safe*/ { auto tests = [ // Ignoring leading spaces. ["ignore leading spaces: 2-2", " ignore leading spaces: 2-1", " ignore leading spaces: 2+1", " ignore leading spaces: 2+0"], // Ignoring multiple adjacent spaces (m.a.s). ["ignore m.a.s spaces: 2-2", "ignore m.a.s spaces: 2-1", "ignore m.a.s spaces: 2+0", "ignore m.a.s spaces: 2+1"], // Equivalent whitespace characters. ["Equiv. spaces: 3-3", "Equiv.\rspaces: 3-2", "Equiv.\x0cspaces: 3-1", "Equiv.\x0bspaces: 3+0", "Equiv.\nspaces: 3+1", "Equiv.\tspaces: 3+2"], // Case Indepenent sort. ["cASE INDEPENENT: 3-2", "caSE INDEPENENT: 3-1", "casE INDEPENENT: 3+0", "case INDEPENENT: 3+1"], // Numeric fields as numerics. ["foo100bar99baz0.txt", "foo100bar10baz0.txt", "foo1000bar99baz10.txt", "foo1000bar99baz9.txt"], // Title sorts. ["The Wind in the Willows", "The 40th step more", "The 39 steps", "Wanda"]]; foreach (test; tests) writeln(test, "\n", test.naturalSort, "\n"); } result: $ dub Performing "debug" build using dmd for x86_64. sort_test ~master: building configuration "application"... source/app.d(19,18): Error: no property 'groupBy' for type 'string' dmd failed with exit code 1.
Feb 06
parent Jonathan M Davis via Digitalmars-d-learn writes:
On Monday, February 06, 2017 17:48:28 Dmitry via Digitalmars-d-learn wrote:
 On Monday, 6 February 2017 at 17:35:02 UTC, Jonathan M Davis

 wrote:
 You have to import std.range to use groupBy.
Of course, "import std.range" already done.
Hmm. Well, the error your getting typically is the error you get when you're missing an import, and I did a quick grep of phobos and saw that groupBy was in std.range, which is why I told you to import std.range. Looking at groupBy more closely now, it's part of SortedRange rather than being a free function, and it doesn't take a predicate. So, I don't know why the Rosetta code example is doing what it's doing. It doesn't match anything that's currently in Phobos. - Jonathan M Davis
Feb 06
prev sibling parent reply =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
On 02/06/2017 08:43 AM, Dmitry wrote:

 Found this https://rosettacode.org/wiki/Natural_sorting#D
 but there is error on ".groupBy!isDigit" (Error: no property 'groupBy'
 for type 'string').
I think it's now std.algorithm.chunkBy. Please fix Rosetta Code as well. Thanks! :) Ali
Feb 06
next sibling parent reply Paolo Invernizzi <paolo.invernizzi no.address> writes:
On Monday, 6 February 2017 at 18:57:17 UTC, Ali Çehreli wrote:
 On 02/06/2017 08:43 AM, Dmitry wrote:

 Found this https://rosettacode.org/wiki/Natural_sorting#D
 but there is error on ".groupBy!isDigit" (Error: no property 
 'groupBy'
 for type 'string').
I think it's now std.algorithm.chunkBy. Please fix Rosetta Code as well. Thanks! :) Ali
I'm missing Bearophile... (and btw, Kenji) /P
Feb 06
parent =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
On 02/06/2017 12:17 PM, Paolo Invernizzi wrote:
 I'm missing Bearophile...
 (and btw, Kenji)
Anybody knows where they are? Rust? Haskell? Something else? :) Ali
Feb 06
prev sibling parent reply Dmitry <dmitry indiedev.ru> writes:
On Monday, 6 February 2017 at 18:57:17 UTC, Ali Çehreli wrote:
 I think  it's now std.algorithm.chunkBy. Please fix Rosetta
Thank you! I fixed, but anyway it works incorrect (it doesn't any changes): Code: https://rosettacode.org/wiki/Natural_sorting#D Result: http://pastebin.com/hhSB4Vpn like this: ["foo1000bar99baz10.txt", "foo1000bar99baz9.txt", "foo100bar10baz0.txt", "foo100bar99baz0.txt"] ["foo1000bar99baz10.txt", "foo1000bar99baz9.txt", "foo100bar10baz0.txt", "foo100bar99baz0.txt"] but must be this: ["foo100bar99baz0.txt", "foo100bar10baz0.txt", "foo1000bar99baz10.txt", "foo1000bar99baz9.txt"] ["foo100bar10baz0.txt", "foo100bar99baz0.txt", "foo1000bar99baz9.txt", "foo1000bar99baz10.txt"]
Feb 06
parent reply =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
On 02/06/2017 09:00 PM, Dmitry wrote:
 On Monday, 6 February 2017 at 18:57:17 UTC, Ali Çehreli wrote:
 I think  it's now std.algorithm.chunkBy. Please fix Rosetta
Thank you! I fixed
Thank you!
 but anyway it works incorrect (it doesn't any changes):
The problem was with the following loop: foreach (test; tests) writeln(test, "\n", test.naturalSort, "\n"); test.naturalSort would sort the array in place before calling writeln and 'test' would appear naturally sorted as well. I've fixed it like this: foreach (test; tests) { printTexts("Test strings", test); printTexts("Normally sorted", test.dup.sort()); printTexts("Naturally sorted", test.dup.naturalSort()); } I had fun inserting "[sic]"s both in source code and in the output for the INDEPENENT typo in the problem description. :D void printTexts(Range)(string tag, Range range) { const sic = range.front.canFind("INDEPENENT") ? " [sic]" : ""; writefln("\n%s%s:\n%-( |%s|%|\n%)", tag, sic, range); } I also made the output more readable: Test strings: |ignore leading spaces: 2-2| | ignore leading spaces: 2-1| | ignore leading spaces: 2+1| | ignore leading spaces: 2+0| Normally sorted: | ignore leading spaces: 2+1| | ignore leading spaces: 2+0| | ignore leading spaces: 2-1| |ignore leading spaces: 2-2| Naturally sorted: | ignore leading spaces: 2+0| | ignore leading spaces: 2+1| | ignore leading spaces: 2-1| |ignore leading spaces: 2-2| [...] Ali
Feb 07
parent reply Dmitry <dmitry indiedev.ru> writes:
On Wednesday, 8 February 2017 at 07:41:29 UTC, Ali Çehreli wrote:
 test.naturalSort would sort the array in place before calling 
 writeln and 'test' would appear naturally sorted as well. I've 
 fixed it like this:
Great! Thank you!
Feb 07
parent =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
On 02/07/2017 11:47 PM, Dmitry wrote:
 On Wednesday, 8 February 2017 at 07:41:29 UTC, Ali Çehreli wrote:
 test.naturalSort would sort the array in place before calling writeln
 and 'test' would appear naturally sorted as well. I've fixed it like
 this:
Great! Thank you!
Well, the title sort is still broken and I can't see my way through it. :-/ Ali
Feb 08