www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Tuple Array Sorting

reply Vino <vino.bheeman hotmail.com> writes:
Hi All,

   Request your help in tuple array sorting, I have a function 
which returns tuple values as below so how do i sort this type of 
array based on the time stamp(Acceding order) .

Eg:
C:\Temp\EXPORT\dir2   2017-Sep-06 16:06:58
C:\Temp\BACKUP\dir2   2017-Sep-09 22:44:11
C:\Temp\TEAM\dir1     2017-Sep-10 16:06:42
C:\Temp\USER\dir3     2017-Sep-05 16:06:57

Required Output:
C:\Temp\USER\dir3     2017-Sep-05 16:06:57
C:\Temp\EXPORT\dir2   2017-Sep-06 16:06:58
C:\Temp\BACKUP\dir2   2017-Sep-09 22:44:11
C:\Temp\TEAM\dir1     2017-Sep-10 16:06:42

From,
Vino.B
Dec 11 2017
parent reply Vino <vino.bheeman hotmail.com> writes:
On Monday, 11 December 2017 at 13:58:49 UTC, Vino wrote:
 Hi All,

   Request your help in tuple array sorting, I have a function 
 which returns tuple values as below so how do i sort this type 
 of array based on the time stamp(Acceding order) .

 Eg:
 C:\Temp\EXPORT\dir2   2017-Sep-06 16:06:58
 C:\Temp\BACKUP\dir2   2017-Sep-09 22:44:11
 C:\Temp\TEAM\dir1     2017-Sep-10 16:06:42
 C:\Temp\USER\dir3     2017-Sep-05 16:06:57

 Required Output:
 C:\Temp\USER\dir3     2017-Sep-05 16:06:57
 C:\Temp\EXPORT\dir2   2017-Sep-06 16:06:58
 C:\Temp\BACKUP\dir2   2017-Sep-09 22:44:11
 C:\Temp\TEAM\dir1     2017-Sep-10 16:06:42

 From,
 Vino.B
A small additional Information C:\Temp\EXPORT\dir2 2017-Sep-06 16:06:58 - Array!(Tuple!(string, string)) (Array 1) C:\Temp\BACKUP\dir2 2017-Sep-09 22:44:11 - Array!(Tuple!(string, string)) (Array 2) C:\Temp\TEAM\dir1 2017-Sep-10 16:06:42 - Array!(Tuple!(string, string)) (Array 3) C:\Temp\USER\dir3 2017-Sep-05 16:06:57 - Array!(Tuple!(string, string)) (Array 4) Required Output: C:\Temp\USER\dir3 2017-Sep-05 16:06:57 - Array!(Tuple!(string, string)) (Array 4) C:\Temp\EXPORT\dir2 2017-Sep-06 16:06:58 - Array!(Tuple!(string, string)) (Array 1) C:\Temp\BACKUP\dir2 2017-Sep-09 22:44:11 - Array!(Tuple!(string, string)) (Array 2) C:\Temp\TEAM\dir1 2017-Sep-10 16:06:42 - Array!(Tuple!(string, string)) (Array 3) From, Vino.B
Dec 11 2017
parent reply Vino <vino.bheeman hotmail.com> writes:
On Monday, 11 December 2017 at 14:25:16 UTC, Vino wrote:
 On Monday, 11 December 2017 at 13:58:49 UTC, Vino wrote:
 Hi All,

   Request your help in tuple array sorting, I have a function 
 which returns tuple values as below so how do i sort this type 
 of array based on the time stamp(Acceding order) .

 Eg:
 C:\Temp\EXPORT\dir2   2017-Sep-06 16:06:58
 C:\Temp\BACKUP\dir2   2017-Sep-09 22:44:11
 C:\Temp\TEAM\dir1     2017-Sep-10 16:06:42
 C:\Temp\USER\dir3     2017-Sep-05 16:06:57

 Required Output:
 C:\Temp\USER\dir3     2017-Sep-05 16:06:57
 C:\Temp\EXPORT\dir2   2017-Sep-06 16:06:58
 C:\Temp\BACKUP\dir2   2017-Sep-09 22:44:11
 C:\Temp\TEAM\dir1     2017-Sep-10 16:06:42

 From,
 Vino.B
A small additional Information C:\Temp\EXPORT\dir2 2017-Sep-06 16:06:58 - Array!(Tuple!(string, string)) (Array 1) C:\Temp\BACKUP\dir2 2017-Sep-09 22:44:11 - Array!(Tuple!(string, string)) (Array 2) C:\Temp\TEAM\dir1 2017-Sep-10 16:06:42 - Array!(Tuple!(string, string)) (Array 3) C:\Temp\USER\dir3 2017-Sep-05 16:06:57 - Array!(Tuple!(string, string)) (Array 4) Required Output: C:\Temp\USER\dir3 2017-Sep-05 16:06:57 - Array!(Tuple!(string, string)) (Array 4) C:\Temp\EXPORT\dir2 2017-Sep-06 16:06:58 - Array!(Tuple!(string, string)) (Array 1) C:\Temp\BACKUP\dir2 2017-Sep-09 22:44:11 - Array!(Tuple!(string, string)) (Array 2) C:\Temp\TEAM\dir1 2017-Sep-10 16:06:42 - Array!(Tuple!(string, string)) (Array 3) From, Vino.B
Example Program and Output import std.algorithm: filter, map, sort; import std.container.array; import std.file: SpanMode, dirEntries, isDir ; import std.range: chain; import std.stdio: writefln; import std.typecons: Tuple, tuple; void main () { auto FFs = Array!(string)("C:\\Temp\\BACKUP", "C:\\Temp\\EXPORT", "C:\\Temp\\PROD_TEAM"); int AgeSize = 2; foreach(d; FFs[]) { auto dFiles = Array!(Tuple!(string, string))(dirEntries(d, SpanMode.shallow).filter!(a => a.isDir).map!(a => tuple(a.name, a.timeCreated.toSimpleString[0 .. 20]))); writefln("%(%-(%-63s %s %)\n%)", chain(dFiles[]).sort!((a,b) => a[0] > b[0])); } } Output C:\Temp\BACKUP\DND3 2017-Sep-05 14:31:00 C:\Temp\BACKUP\dir1 2017-Sep-06 16:06:42 C:\Temp\BACKUP\dir2 2017-Sep-09 22:44:11 C:\Temp\BACKUP\dir3 2017-Dec-10 06:56:07 C:\Temp\BACKUP\t1 2017-Dec-11 04:10:02 C:\Temp\EXPORT\DND6 2017-Sep-05 14:31:00 C:\Temp\PROD_TEAM\DND1 2017-Sep-05 14:31:01 Output Required C:\Temp\BACKUP\DND3 2017-Sep-05 14:31:00 C:\Temp\EXPORT\DND6 2017-Sep-05 14:31:00 C:\Temp\PROD_TEAM\DND1 2017-Sep-05 14:31:01 C:\Temp\BACKUP\dir1 2017-Sep-06 16:06:42 C:\Temp\BACKUP\dir2 2017-Sep-09 22:44:11 C:\Temp\BACKUP\dir3 2017-Dec-10 06:56:07 C:\Temp\BACKUP\t1 2017-Dec-11 04:10:02 From, Vino.B
Dec 11 2017
parent reply Biotronic <simen.kjaras gmail.com> writes:
On Monday, 11 December 2017 at 14:52:35 UTC, Vino wrote:
 Example Program and Output

 import std.algorithm: filter, map, sort;
 import std.container.array;
 import std.file: SpanMode, dirEntries, isDir ;
 import std.range: chain;
 import std.stdio: writefln;
 import std.typecons: Tuple, tuple;

 void main () {
 auto FFs =  Array!(string)("C:\\Temp\\BACKUP", 
 "C:\\Temp\\EXPORT", "C:\\Temp\\PROD_TEAM");
 int AgeSize = 2;
 foreach(d; FFs[]) {
 auto dFiles = Array!(Tuple!(string, string))(dirEntries(d, 
 SpanMode.shallow).filter!(a => a.isDir).map!(a => tuple(a.name, 
 a.timeCreated.toSimpleString[0 .. 20])));
 writefln("%(%-(%-63s %s %)\n%)", chain(dFiles[]).sort!((a,b) => 
 a[0] > b[0]));
 }
 }
You're somewhat close. You're sorting based on the 0th element of your tuples, while you should sort on the 1st. Something like this: import std.algorithm: filter, map, sort; import std.array : array; import std.file: SpanMode, dirEntries, isDir ; import std.range: join; import std.stdio: writefln; import std.typecons: tuple; void main () { auto folders = ["D:\\Dev"]; auto sorted = folders .map!(a => dirEntries(a, SpanMode.shallow)) .join .filter!(a => a.isDir) .map!(a => tuple(a.name, a.timeCreated.toSimpleString[0 .. 20])) .array .sort!((a,b) => a[1] > b[1]); writefln("%( %( %-63s %s %) \n%)", sorted); } -- Biotronic
Dec 11 2017
parent reply Vino <vino.bheeman hotmail.com> writes:
On Monday, 11 December 2017 at 15:15:47 UTC, Biotronic wrote:
 On Monday, 11 December 2017 at 14:52:35 UTC, Vino wrote:
 Example Program and Output

 import std.algorithm: filter, map, sort;
 import std.container.array;
 import std.file: SpanMode, dirEntries, isDir ;
 import std.range: chain;
 import std.stdio: writefln;
 import std.typecons: Tuple, tuple;

 void main () {
 auto FFs =  Array!(string)("C:\\Temp\\BACKUP", 
 "C:\\Temp\\EXPORT", "C:\\Temp\\PROD_TEAM");
 int AgeSize = 2;
 foreach(d; FFs[]) {
 auto dFiles = Array!(Tuple!(string, string))(dirEntries(d, 
 SpanMode.shallow).filter!(a => a.isDir).map!(a => 
 tuple(a.name, a.timeCreated.toSimpleString[0 .. 20])));
 writefln("%(%-(%-63s %s %)\n%)", chain(dFiles[]).sort!((a,b) 
 => a[0] > b[0]));
 }
 }
You're somewhat close. You're sorting based on the 0th element of your tuples, while you should sort on the 1st. Something like this: import std.algorithm: filter, map, sort; import std.array : array; import std.file: SpanMode, dirEntries, isDir ; import std.range: join; import std.stdio: writefln; import std.typecons: tuple; void main () { auto folders = ["D:\\Dev"]; auto sorted = folders .map!(a => dirEntries(a, SpanMode.shallow)) .join .filter!(a => a.isDir) .map!(a => tuple(a.name, a.timeCreated.toSimpleString[0 .. 20])) .array .sort!((a,b) => a[1] > b[1]); writefln("%( %( %-63s %s %) \n%)", sorted); } -- Biotronic
Hi, I tired that but no luck, below is the output, in your code you have one folder "auto folders = ["D:\\Dev"];" if you have multiple folder then output is not sorted. C:\Temp\BACKUP\dir2 2017-Sep-09 22:44:11 C:\Temp\BACKUP\dir1 2017-Sep-06 16:06:42 C:\Temp\BACKUP\DND3 2017-Sep-05 14:31:00 C:\Temp\BACKUP\t1 2017-Dec-11 04:10:02 C:\Temp\BACKUP\dir3 2017-Dec-10 06:56:07 C:\Temp\EXPORT\DND6 2017-Sep-05 14:31:00 C:\Temp\PROD_TEAM\DND1 2017-Sep-05 14:31:01 From, Vino.B
Dec 11 2017
next sibling parent Biotronic <simen.kjaras gmail.com> writes:
On Monday, 11 December 2017 at 15:33:08 UTC, Vino wrote:
  I tired that but no luck, below is the output, in your code 
 you have one folder "auto folders =  ["D:\\Dev"];" if you have 
 multiple folder then output is not sorted.
Works on my machine. Of course, since time toSimpleString returns non-ISO8601, the sorting might not make perfect sense ("2017-Dec-12" < "2017-Jan-01"). Testing with multiple folders gives perfectly sorted output. If you want it sorted by date instead of by string representation of date, feel free to remove .toSimpleString[0 .. 20]. -- Biotronic
Dec 11 2017
prev sibling parent reply Biotronic <simen.kjaras gmail.com> writes:
On Monday, 11 December 2017 at 15:33:08 UTC, Vino wrote:
 On Monday, 11 December 2017 at 15:15:47 UTC, Biotronic wrote:
 On Monday, 11 December 2017 at 14:52:35 UTC, Vino wrote:
 Example Program and Output

 import std.algorithm: filter, map, sort;
 import std.container.array;
 import std.file: SpanMode, dirEntries, isDir ;
 import std.range: chain;
 import std.stdio: writefln;
 import std.typecons: Tuple, tuple;

 void main () {
 auto FFs =  Array!(string)("C:\\Temp\\BACKUP", 
 "C:\\Temp\\EXPORT", "C:\\Temp\\PROD_TEAM");
 int AgeSize = 2;
 foreach(d; FFs[]) {
 auto dFiles = Array!(Tuple!(string, string))(dirEntries(d, 
 SpanMode.shallow).filter!(a => a.isDir).map!(a => 
 tuple(a.name, a.timeCreated.toSimpleString[0 .. 20])));
 writefln("%(%-(%-63s %s %)\n%)", chain(dFiles[]).sort!((a,b) 
 => a[0] > b[0]));
 }
 }
You're somewhat close. You're sorting based on the 0th element of your tuples, while you should sort on the 1st. Something like this: import std.algorithm: filter, map, sort; import std.array : array; import std.file: SpanMode, dirEntries, isDir ; import std.range: join; import std.stdio: writefln; import std.typecons: tuple; void main () { auto folders = ["D:\\Dev"]; auto sorted = folders .map!(a => dirEntries(a, SpanMode.shallow)) .join .filter!(a => a.isDir) .map!(a => tuple(a.name, a.timeCreated.toSimpleString[0 .. 20])) .array .sort!((a,b) => a[1] > b[1]); writefln("%( %( %-63s %s %) \n%)", sorted); } -- Biotronic
Hi, I tired that but no luck, below is the output, in your code you have one folder "auto folders = ["D:\\Dev"];" if you have multiple folder then output is not sorted. C:\Temp\BACKUP\dir2 2017-Sep-09 22:44:11 C:\Temp\BACKUP\dir1 2017-Sep-06 16:06:42 C:\Temp\BACKUP\DND3 2017-Sep-05 14:31:00 C:\Temp\BACKUP\t1 2017-Dec-11 04:10:02 C:\Temp\BACKUP\dir3 2017-Dec-10 06:56:07 C:\Temp\EXPORT\DND6 2017-Sep-05 14:31:00 C:\Temp\PROD_TEAM\DND1 2017-Sep-05 14:31:01
Are you sure that's the output from my code? Let's step through the code: // Iterating over folders: folders // Create a range where each element is a range of DirEntry // in the given folder. .map!(a => dirEntries(a, SpanMode.shallow)) // Join these together to a single range of DirEntry instead of // a range-of-ranges-of-DirEntry. .join // Remove anything that's not a folder. .filter!(a => a.isDir) // Grab the information we actually care about. .map!(a => tuple(a.name, a.timeCreated)) // Enumerate to an array, so we can sort it. .array // Sort this array by the second tuple element (timeCreated). .sort!((a,b) => a[1] > b[1]); If this code does not do what you're asking, there's a bug outside of the code, probably in the standard library. If instead you are invoking the program multiple times with a single folder each time, the output you describe is to be expected. Apart from that, I'm not sure what could be wrong. -- Biotronic
Dec 11 2017
parent reply Vino <vino.bheeman hotmail.com> writes:
On Monday, 11 December 2017 at 15:54:11 UTC, Biotronic wrote:
 On Monday, 11 December 2017 at 15:33:08 UTC, Vino wrote:
 On Monday, 11 December 2017 at 15:15:47 UTC, Biotronic wrote:
   [...]
Hi, I tired that but no luck, below is the output, in your code you have one folder "auto folders = ["D:\\Dev"];" if you have multiple folder then output is not sorted. C:\Temp\BACKUP\dir2 2017-Sep-09 22:44:11 C:\Temp\BACKUP\dir1 2017-Sep-06 16:06:42 C:\Temp\BACKUP\DND3 2017-Sep-05 14:31:00 C:\Temp\BACKUP\t1 2017-Dec-11 04:10:02 C:\Temp\BACKUP\dir3 2017-Dec-10 06:56:07 C:\Temp\EXPORT\DND6 2017-Sep-05 14:31:00 C:\Temp\PROD_TEAM\DND1 2017-Sep-05 14:31:01
Are you sure that's the output from my code? Let's step through the code: // Iterating over folders: folders // Create a range where each element is a range of DirEntry // in the given folder. .map!(a => dirEntries(a, SpanMode.shallow)) // Join these together to a single range of DirEntry instead of // a range-of-ranges-of-DirEntry. .join // Remove anything that's not a folder. .filter!(a => a.isDir) // Grab the information we actually care about. .map!(a => tuple(a.name, a.timeCreated)) // Enumerate to an array, so we can sort it. .array // Sort this array by the second tuple element (timeCreated). .sort!((a,b) => a[1] > b[1]); If this code does not do what you're asking, there's a bug outside of the code, probably in the standard library. If instead you are invoking the program multiple times with a single folder each time, the output you describe is to be expected. Apart from that, I'm not sure what could be wrong. -- Biotronic
Hi Biotronic, I tried your code with multiple folder's , but no luck the output is not sorted. Program: import std.algorithm: filter, map, sort; import std.array; import std.file: SpanMode, dirEntries, isDir ; import std.stdio: writefln, writeln; import std.typecons: Tuple, tuple; void main () { auto FFs = ["C:\\Temp\\sapnas2\\BACKUP", "C:\\Temp\\sapnas2\\EXPORT", "C:\\Temp\\sapnas2\\PROD_TEAM"]; auto sorted = FFs .map!(a => dirEntries(a, SpanMode.shallow)) .join .filter!(a => a.isDir) .map!(a => tuple(a.name, a.timeCreated.toSimpleString[0 .. 20])) .array .sort!((a,b) => a[1] > b[1]); writefln("%( %( %-63s %s %) \n%)", sorted); } From, Vino.B
Dec 11 2017
parent reply Seb <seb wilzba.ch> writes:
On Monday, 11 December 2017 at 16:15:14 UTC, Vino wrote:
 On Monday, 11 December 2017 at 15:54:11 UTC, Biotronic wrote:
   [...]
Hi Biotronic, I tried your code with multiple folder's , but no luck the output is not sorted. Program: import std.algorithm: filter, map, sort; import std.array; import std.file: SpanMode, dirEntries, isDir ; import std.stdio: writefln, writeln; import std.typecons: Tuple, tuple; void main () { auto FFs = ["C:\\Temp\\sapnas2\\BACKUP", "C:\\Temp\\sapnas2\\EXPORT", "C:\\Temp\\sapnas2\\PROD_TEAM"]; auto sorted = FFs .map!(a => dirEntries(a, SpanMode.shallow)) .join .filter!(a => a.isDir) .map!(a => tuple(a.name, a.timeCreated.toSimpleString[0 .. 20])) .array .sort!((a,b) => a[1] > b[1]); writefln("%( %( %-63s %s %) \n%)", sorted); } From, Vino.B
Your program still contains toSimpleString in the sort lambda. Have you, as suggested, removed it? As Biotronic explained, sorting on the string representation of dates can't work.
Dec 11 2017
parent reply Vino <vino.bheeman hotmail.com> writes:
On Monday, 11 December 2017 at 19:23:40 UTC, Seb wrote:
 On Monday, 11 December 2017 at 16:15:14 UTC, Vino wrote:
 On Monday, 11 December 2017 at 15:54:11 UTC, Biotronic wrote:
   [...]
Hi Biotronic, I tried your code with multiple folder's , but no luck the output is not sorted. Program: import std.algorithm: filter, map, sort; import std.array; import std.file: SpanMode, dirEntries, isDir ; import std.stdio: writefln, writeln; import std.typecons: Tuple, tuple; void main () { auto FFs = ["C:\\Temp\\sapnas2\\BACKUP", "C:\\Temp\\sapnas2\\EXPORT", "C:\\Temp\\sapnas2\\PROD_TEAM"]; auto sorted = FFs .map!(a => dirEntries(a, SpanMode.shallow)) .join .filter!(a => a.isDir) .map!(a => tuple(a.name, a.timeCreated.toSimpleString[0 .. 20])) .array .sort!((a,b) => a[1] > b[1]); writefln("%( %( %-63s %s %) \n%)", sorted); } From, Vino.B
Your program still contains toSimpleString in the sort lambda. Have you, as suggested, removed it? As Biotronic explained, sorting on the string representation of dates can't work.
Hi, Yes, I have changed the code as below, and removed the toSimpleString, even then no luck. Code: import std.algorithm; import std.container.array; import std.file: SpanMode, dirEntries, isDir ; import std.stdio: writefln, writeln; import std.typecons: Tuple, tuple; import std.range: chain; void main () { auto FFs = ["C:\\Temp\\BACKUP", "C:\\Temp\\EXPORT", "C:\\Temp\\PROD_TEAM"]; foreach(d; FFs[]) { auto dFiles = Array!(Tuple!(string, SysTime))(dirEntries(d, SpanMode.shallow).filter!(a => a.isDir).map!(a => tuple(a.name, a.timeCreated))); writefln("%(%-(%-63s %s %)\n%)", chain(dFiles[]).sort!((a, b) => a[1] < b[1])); } } Output C:\Temp\BACKUP\DND3 2017-Sep-05 14:31:00.7037169 C:\Temp\BACKUP\dir1 2017-Sep-06 16:06:42.7223837 C:\Temp\BACKUP\dir2 2017-Sep-09 22:44:11.7604069 C:\Temp\BACKUP\dir3 2017-Dec-10 06:56:07.5122231 C:\Temp\BACKUP\t1 2017-Dec-11 04:10:02.6413853 C:\Temp\EXPORT\DND6 2017-Sep-05 14:31:00.8909172 C:\Temp\PROD_TEAM\DND1 2017-Sep-05 14:31:01.8269189 Required Output: C:\Temp\BACKUP\DND3 2017-Sep-05 14:31:00.7037169 C:\Temp\EXPORT\DND6 2017-Sep-05 14:31:00.8909172 C:\Temp\PROD_TEAM\DND1 2017-Sep-05 14:31:01.8269189 C:\Temp\BACKUP\dir1 2017-Sep-06 16:06:42.7223837 C:\Temp\BACKUP\dir2 2017-Sep-09 22:44:11.7604069 C:\Temp\BACKUP\dir3 2017-Dec-10 06:56:07.5122231 C:\Temp\BACKUP\t1 2017-Dec-11 04:10:02.6413853 From, Vino.B
Dec 11 2017
parent reply Biotronic <simen.kjaras gmail.com> writes:
On Monday, 11 December 2017 at 19:46:04 UTC, Vino wrote:

 import std.algorithm;
 import std.container.array;
 import std.file: SpanMode, dirEntries, isDir ;
 import std.stdio: writefln, writeln;
 import std.typecons: Tuple, tuple;
 import std.range: chain;

 void main () {
 auto FFs =  ["C:\\Temp\\BACKUP", "C:\\Temp\\EXPORT", 
 "C:\\Temp\\PROD_TEAM"];
 foreach(d; FFs[]) {
 auto dFiles = Array!(Tuple!(string, SysTime))(dirEntries(d, 
 SpanMode.shallow).filter!(a => a.isDir).map!(a => tuple(a.name, 
 a.timeCreated)));
 writefln("%(%-(%-63s %s %)\n%)", chain(dFiles[]).sort!((a, b) 
 => a[1] < b[1]));
 }
 }
So let's go through this code then, shall we? Edited a bit for clarity: // For each directory (*one at a time*), foreach(d; FFs[]) { // List all the folders auto dFiles = Array!(Tuple!(string, SysTime))( dirEntries(d, SpanMode.shallow) // Not the files, .filter!(a => a.isDir) // Grab only the information we want, .map!(a => tuple(a.name, a.timeCreated))); // And print a sorted list of the subfolders of the current folder. writefln("%(%-(%-63s %s %)\n%)", chain(dFiles[]).sort!((a, b) => a[1] < b[1])); } This will go through C:\Temp\BACKUP, and display a sorted list of all the subfolders in that folder. Then it will do the same for C:\Temp\EXPORT, and then for C:\Temp\PROD_TEAM. No subfolder of C:\Temp\PROD_TEAM will be displayed before anything in C:\Temp\BACKUP, because you're sorting only one set of subfolders at a time. What you're essentially doing, is sorting [6,2,4] and [3,5,1] separately, and printing them separately, giving the illusion of having sorted them into the array [2,4,6,1,3,5]. As you correctly point out, this is not what you wanted. The code I presented avoids this by joining the lists for all the folders. Your code could also be simplified a bit - there's no need for the call to chain, and calling dirEntries.filter.map.array is easier to read and write than having Array!(Tuple!(string, SysTime)) at the front. In case my code from earlier was hard to understand, here's another version~, more closely modeled to your code: import std.algorithm : map, filter, sort; import std.array : array; import std.file : SpanMode, dirEntries, isDir; import std.stdio : writefln; import std.typecons : Tuple, tuple; import std.datetime : SysTime; void main() { // The folders we want to look in. auto folders = [`C:\Windows`, `C:\Program Files`, `C:\Users`]; // We'll put all the subfolders we find here, so we can sort them in the end. Tuple!(string, SysTime)[] subFolders; // Look through each folder in turn. foreach (folder; folders) { // Get all entries in the folder, auto entries = dirEntries(folder, SpanMode.shallow); // Get rid of files, auto folderEntries = entries.filter!(a => a.isDir); // Grab the interesting parts, auto interestingParts = folderEntries.map!(a => tuple(a.name, a.timeCreated)); // And add it to the array. subFolders ~= interestingParts.array; } // Sort the entire array. auto sorted = subFolders.sort!((a, b) => a[1] < b[1]); // And print it! writefln("%(%-(%-63s %s %)\n%)", sorted); }
Dec 11 2017
parent reply Vino <vino.bheeman hotmail.com> writes:
On Monday, 11 December 2017 at 20:58:31 UTC, Biotronic wrote:
 On Monday, 11 December 2017 at 19:46:04 UTC, Vino wrote:

 import std.algorithm;
 import std.container.array;
 import std.file: SpanMode, dirEntries, isDir ;
 import std.stdio: writefln, writeln;
 import std.typecons: Tuple, tuple;
 import std.range: chain;

 void main () {
 auto FFs =  ["C:\\Temp\\BACKUP", "C:\\Temp\\EXPORT", 
 "C:\\Temp\\PROD_TEAM"];
 foreach(d; FFs[]) {
 auto dFiles = Array!(Tuple!(string, SysTime))(dirEntries(d, 
 SpanMode.shallow).filter!(a => a.isDir).map!(a => 
 tuple(a.name, a.timeCreated)));
 writefln("%(%-(%-63s %s %)\n%)", chain(dFiles[]).sort!((a, b) 
 => a[1] < b[1]));
 }
 }
So let's go through this code then, shall we? Edited a bit for clarity: // For each directory (*one at a time*), foreach(d; FFs[]) { // List all the folders auto dFiles = Array!(Tuple!(string, SysTime))( dirEntries(d, SpanMode.shallow) // Not the files, .filter!(a => a.isDir) // Grab only the information we want, .map!(a => tuple(a.name, a.timeCreated))); // And print a sorted list of the subfolders of the current folder. writefln("%(%-(%-63s %s %)\n%)", chain(dFiles[]).sort!((a, b) => a[1] < b[1])); } This will go through C:\Temp\BACKUP, and display a sorted list of all the subfolders in that folder. Then it will do the same for C:\Temp\EXPORT, and then for C:\Temp\PROD_TEAM. No subfolder of C:\Temp\PROD_TEAM will be displayed before anything in C:\Temp\BACKUP, because you're sorting only one set of subfolders at a time. What you're essentially doing, is sorting [6,2,4] and [3,5,1] separately, and printing them separately, giving the illusion of having sorted them into the array [2,4,6,1,3,5]. As you correctly point out, this is not what you wanted. The code I presented avoids this by joining the lists for all the folders. Your code could also be simplified a bit - there's no need for the call to chain, and calling dirEntries.filter.map.array is easier to read and write than having Array!(Tuple!(string, SysTime)) at the front. In case my code from earlier was hard to understand, here's another version~, more closely modeled to your code: import std.algorithm : map, filter, sort; import std.array : array; import std.file : SpanMode, dirEntries, isDir; import std.stdio : writefln; import std.typecons : Tuple, tuple; import std.datetime : SysTime; void main() { // The folders we want to look in. auto folders = [`C:\Windows`, `C:\Program Files`, `C:\Users`]; // We'll put all the subfolders we find here, so we can sort them in the end. Tuple!(string, SysTime)[] subFolders; // Look through each folder in turn. foreach (folder; folders) { // Get all entries in the folder, auto entries = dirEntries(folder, SpanMode.shallow); // Get rid of files, auto folderEntries = entries.filter!(a => a.isDir); // Grab the interesting parts, auto interestingParts = folderEntries.map!(a => tuple(a.name, a.timeCreated)); // And add it to the array. subFolders ~= interestingParts.array; } // Sort the entire array. auto sorted = subFolders.sort!((a, b) => a[1] < b[1]); // And print it! writefln("%(%-(%-63s %s %)\n%)", sorted); }
Hi, Thank you very much , was able to resolve the issue using your logic with a bit of addition and not i am getting the sorted output as expected, except that the date and time are displayed as "2017-Sep-05 14:31:00.7037169" so may i know how do we get the output as "2017-Sep-05 14:31:00". Program: import std.algorithm: filter, map, sort; import std.container.array; import std.file: SpanMode, dirEntries, isDir ; import std.stdio: writefln; import std.typecons: Tuple, tuple; import std.datetime.systime: SysTime; void main () { auto FFs = ["C:\\Temp\\sapnas2\\BACKUP", "C:\\Temp\\sapnas2\\EXPORT", "C:\\Temp\\sapnas2\\PROD_TEAM"]; Array!(Tuple!(string, SysTime)) Result; foreach(d; FFs[]) { auto dFiles = Array!(Tuple!(string, SysTime))(dirEntries(d, SpanMode.shallow).filter!(a => a.isDir).map!(a => tuple(a.name, a.timeCreated))); foreach(e; dFiles) { Result ~= e; } } writefln("%(%-(%-63s %.20s %)\n%)", Result[].sort!((a, b) => a[1] < b[1])); } From, Vino.B
Dec 12 2017
parent reply Biotronic <simen.kjaras gmail.com> writes:
On Tuesday, 12 December 2017 at 15:19:35 UTC, Vino wrote:
 import std.algorithm: filter, map, sort;
 import std.container.array;
 import std.file: SpanMode, dirEntries, isDir ;
 import std.stdio: writefln;
 import std.typecons: Tuple, tuple;
 import std.datetime.systime: SysTime;

 void main () {
 auto FFs =  ["C:\\Temp\\sapnas2\\BACKUP", 
 "C:\\Temp\\sapnas2\\EXPORT", "C:\\Temp\\sapnas2\\PROD_TEAM"];
 Array!(Tuple!(string, SysTime)) Result;
 foreach(d; FFs[]) {
 	auto dFiles = Array!(Tuple!(string, SysTime))(dirEntries(d, 
 SpanMode.shallow).filter!(a => a.isDir).map!(a => tuple(a.name, 
 a.timeCreated)));
 	foreach(e; dFiles) { Result ~= e; } }
     writefln("%(%-(%-63s %.20s %)\n%)", Result[].sort!((a, b) 
 => a[1] < b[1]));
 }
Since there's little need to extract timeCreated and name before sorting, here's a version that doesn't: import std.algorithm : map, filter, sort; import std.array : array; import std.range : join; import std.file : SpanMode, dirEntries, isDir; import std.stdio : writefln; import std.typecons : tuple; void main() { auto folders = [`C:\Windows`, `C:\Program Files`, `C:\Users`]; auto sorted = folders .map!(f => f.dirEntries(SpanMode.shallow)) .join .filter!(e => e.isDir) .array .sort!((a,b) => a.timeCreated < b.timeCreated) .map!(e => tuple(e.name, e.timeCreated.toSimpleString[0 .. 20])); writefln("%(%-(%-63s %s %)\n%)", sorted); } And a version with normal loops, since the heavily range-based version above can be a bit dense. These programs do essentially the same thing: import std.algorithm : sort; import std.array : array; import std.file : SpanMode, dirEntries, DirEntry, isDir; import std.stdio : writefln; import std.typecons : tuple, Tuple; void main() { auto folders = [`C:\Windows`, `C:\Program Files`, `C:\Users`]; DirEntry[] subFolders; foreach (folder; folders) { auto children = dirEntries(folder, SpanMode.shallow); foreach (child; children) { if (child.isDir) subFolders ~= child; } } subFolders.sort!((a,b) => a.timeCreated < b.timeCreated); Tuple!(string, string)[] interestingParts; foreach (subFolder; subFolders) { interestingParts ~= tuple(subFolder.name, subFolder.timeCreated.toSimpleString[0..20]); } writefln("%(%-(%-63s %s %)\n%)", interestingParts); } As you can see, I'm just chopping off the parts I don't like from toSimpleString. It seems a good format function for dates does not exist in Phobos. -- Biotronic
Dec 12 2017
next sibling parent Vino <vino.bheeman hotmail.com> writes:
On Tuesday, 12 December 2017 at 19:00:01 UTC, Biotronic wrote:
 On Tuesday, 12 December 2017 at 15:19:35 UTC, Vino wrote:
 import std.algorithm: filter, map, sort;
 import std.container.array;
 import std.file: SpanMode, dirEntries, isDir ;
 import std.stdio: writefln;
 import std.typecons: Tuple, tuple;
 import std.datetime.systime: SysTime;

 void main () {
 auto FFs =  ["C:\\Temp\\sapnas2\\BACKUP", 
 "C:\\Temp\\sapnas2\\EXPORT", "C:\\Temp\\sapnas2\\PROD_TEAM"];
 Array!(Tuple!(string, SysTime)) Result;
 foreach(d; FFs[]) {
 	auto dFiles = Array!(Tuple!(string, SysTime))(dirEntries(d, 
 SpanMode.shallow).filter!(a => a.isDir).map!(a => 
 tuple(a.name, a.timeCreated)));
 	foreach(e; dFiles) { Result ~= e; } }
     writefln("%(%-(%-63s %.20s %)\n%)", Result[].sort!((a, b) 
 => a[1] < b[1]));
 }
Since there's little need to extract timeCreated and name before sorting, here's a version that doesn't: import std.algorithm : map, filter, sort; import std.array : array; import std.range : join; import std.file : SpanMode, dirEntries, isDir; import std.stdio : writefln; import std.typecons : tuple; void main() { auto folders = [`C:\Windows`, `C:\Program Files`, `C:\Users`]; auto sorted = folders .map!(f => f.dirEntries(SpanMode.shallow)) .join .filter!(e => e.isDir) .array .sort!((a,b) => a.timeCreated < b.timeCreated) .map!(e => tuple(e.name, e.timeCreated.toSimpleString[0 .. 20])); writefln("%(%-(%-63s %s %)\n%)", sorted); } And a version with normal loops, since the heavily range-based version above can be a bit dense. These programs do essentially the same thing: import std.algorithm : sort; import std.array : array; import std.file : SpanMode, dirEntries, DirEntry, isDir; import std.stdio : writefln; import std.typecons : tuple, Tuple; void main() { auto folders = [`C:\Windows`, `C:\Program Files`, `C:\Users`]; DirEntry[] subFolders; foreach (folder; folders) { auto children = dirEntries(folder, SpanMode.shallow); foreach (child; children) { if (child.isDir) subFolders ~= child; } } subFolders.sort!((a,b) => a.timeCreated < b.timeCreated); Tuple!(string, string)[] interestingParts; foreach (subFolder; subFolders) { interestingParts ~= tuple(subFolder.name, subFolder.timeCreated.toSimpleString[0..20]); } writefln("%(%-(%-63s %s %)\n%)", interestingParts); } As you can see, I'm just chopping off the parts I don't like from toSimpleString. It seems a good format function for dates does not exist in Phobos. -- Biotronic
Hi Biotronic, I was able to find a solution using container array and also date formatting, below is the code, please do let me know if you find any issue, as i have tested the script and it is working as expected. Program: import std.algorithm: filter, map, sort, each; import std.container.array; import std.file: SpanMode, dirEntries, isDir ; import std.stdio: writeln,writefln; import std.typecons: Tuple, tuple; import std.datetime.systime: SysTime; import std.conv; void main () { auto FFs = ["C:\\Temp\\sapnas2\\BACKUP", "C:\\Temp\\sapnas2\\EXPORT"]; Array!(Tuple!(string, SysTime)) Sorted; foreach(d; FFs[]) { auto dFiles = Array!(Tuple!(string, SysTime))(dirEntries(d, SpanMode.shallow).filter!(a => a.isDir).map!(a => tuple(a.name, a.timeCreated))); foreach(i; dFiles[]){ Sorted ~= i; } Sorted[].sort!((a,b) => a[1] > b[1]).each!(e => writefln!"%-63s %.20s"(e[0], e[1].to!string)); } } From, Vino.B
Dec 13 2017
prev sibling parent reply Vino <vino.bheeman hotmail.com> writes:
On Tuesday, 12 December 2017 at 19:00:01 UTC, Biotronic wrote:
 On Tuesday, 12 December 2017 at 15:19:35 UTC, Vino wrote:
 import std.algorithm: filter, map, sort;
 import std.container.array;
 import std.file: SpanMode, dirEntries, isDir ;
 import std.stdio: writefln;
 import std.typecons: Tuple, tuple;
 import std.datetime.systime: SysTime;

 void main () {
 auto FFs =  ["C:\\Temp\\sapnas2\\BACKUP", 
 "C:\\Temp\\sapnas2\\EXPORT", "C:\\Temp\\sapnas2\\PROD_TEAM"];
 Array!(Tuple!(string, SysTime)) Result;
 foreach(d; FFs[]) {
 	auto dFiles = Array!(Tuple!(string, SysTime))(dirEntries(d, 
 SpanMode.shallow).filter!(a => a.isDir).map!(a => 
 tuple(a.name, a.timeCreated)));
 	foreach(e; dFiles) { Result ~= e; } }
     writefln("%(%-(%-63s %.20s %)\n%)", Result[].sort!((a, b) 
 => a[1] < b[1]));
 }
Since there's little need to extract timeCreated and name before sorting, here's a version that doesn't: import std.algorithm : map, filter, sort; import std.array : array; import std.range : join; import std.file : SpanMode, dirEntries, isDir; import std.stdio : writefln; import std.typecons : tuple; void main() { auto folders = [`C:\Windows`, `C:\Program Files`, `C:\Users`]; auto sorted = folders .map!(f => f.dirEntries(SpanMode.shallow)) .join .filter!(e => e.isDir) .array .sort!((a,b) => a.timeCreated < b.timeCreated) .map!(e => tuple(e.name, e.timeCreated.toSimpleString[0 .. 20])); writefln("%(%-(%-63s %s %)\n%)", sorted); } And a version with normal loops, since the heavily range-based version above can be a bit dense. These programs do essentially the same thing: import std.algorithm : sort; import std.array : array; import std.file : SpanMode, dirEntries, DirEntry, isDir; import std.stdio : writefln; import std.typecons : tuple, Tuple; void main() { auto folders = [`C:\Windows`, `C:\Program Files`, `C:\Users`]; DirEntry[] subFolders; foreach (folder; folders) { auto children = dirEntries(folder, SpanMode.shallow); foreach (child; children) { if (child.isDir) subFolders ~= child; } } subFolders.sort!((a,b) => a.timeCreated < b.timeCreated); Tuple!(string, string)[] interestingParts; foreach (subFolder; subFolders) { interestingParts ~= tuple(subFolder.name, subFolder.timeCreated.toSimpleString[0..20]); } writefln("%(%-(%-63s %s %)\n%)", interestingParts); } As you can see, I'm just chopping off the parts I don't like from toSimpleString. It seems a good format function for dates does not exist in Phobos. -- Biotronic
Hi Biotronic, I was able to find a solution using container array and also date formatting, below is the code, please do let me know if you find any issue, as i have tested the script and it is working as expected. Program: import std.algorithm: filter, map, sort, each; import std.container.array; import std.file: SpanMode, dirEntries, isDir ; import std.stdio: writeln,writefln; import std.typecons: Tuple, tuple; import std.datetime.systime: SysTime; import std.conv; void main () { auto FFs = ["C:\\Temp\\sapnas2\\BACKUP", "C:\\Temp\\sapnas2\\EXPORT"]; Array!(Tuple!(string, SysTime)) Sorted; foreach(d; FFs[]) { auto dFiles = Array!(Tuple!(string, SysTime))(dirEntries(d, SpanMode.shallow).filter!(a => a.isDir).map!(a => tuple(a.name, a.timeCreated))); foreach(i; dFiles[]){ Sorted ~= i; } Sorted[].sort!((a,b) => a[1] > b[1]).each!(e => writefln!"%-63s %.20s"(e[0], e[1].to!string)); } } From, Vino.B
Dec 15 2017
parent Biotronic <simen.kjaras gmail.com> writes:
On Friday, 15 December 2017 at 17:24:33 UTC, Vino wrote:
 Hi Biotronic,

  I was able to find a solution using container array and also 
 date formatting, below is the code, please do let me know if 
 you find any issue, as i have tested the script and it is 
 working as expected.

 Program:
 import std.algorithm: filter, map, sort, each;
 import std.container.array;
 import std.file: SpanMode, dirEntries, isDir ;
 import std.stdio: writeln,writefln;
 import std.typecons: Tuple, tuple;
 import std.datetime.systime: SysTime;
 import std.conv;
 void main () {
 auto FFs =  ["C:\\Temp\\sapnas2\\BACKUP", 
 "C:\\Temp\\sapnas2\\EXPORT"];
 Array!(Tuple!(string, SysTime)) Sorted;
 foreach(d; FFs[]) {
 auto dFiles = Array!(Tuple!(string, SysTime))(dirEntries(d,
Why specify Array!(Tuple!(string, SysTime)) here? The return value from map should be perfectly fine, and if you really want an array I'd suggest writing dirEntries(d, SpanMode.shallow) .filter!(a => a.isDir) .map!(a => tuple(a.name, a.timeCreated))) .array; It's shorter, easier to read, and the speed difference should be miniscule at best. The same comment applies to Sorted, above, which could be defined as Tuple!(string, SysTime)[].
 SpanMode.shallow).filter!(a => a.isDir).map!(a => tuple(a.name, 
 a.timeCreated)));
 foreach(i; dFiles[]){ Sorted ~= i; }
No need for a foreach here, you can just do Sorted ~= dFiles.
 Sorted[].sort!((a,b) => a[1] > b[1]).each!(e => writefln!"%-63s 
 %.20s"(e[0], e[1].to!string));
You seem to be sorting and printing the Sorted array once per folder. Going back to [3,5,1], [6,2,4] example, this will print 1,3,5,1,2,3,4,5,6. That is, it sorts [3,5,1], then prints the result. Then it sorts [1,3,5,6,2,4], and prints that. If you move the sorting and priting outside the loop (so it's the last line before leaving main), you should get the correct result, and and not waste time sorting the array multiple times.
 }
 }
In total, the changes I propose would lead to this code: import std.algorithm: filter, map, sort, each; import std.array : array; import std.file: SpanMode, dirEntries, isDir ; import std.stdio: writefln; import std.typecons: Tuple, tuple; import std.datetime.systime: SysTime; import std.conv : to; void main () { auto FFs = ["C:\\Temp\\sapnas2\\BACKUP", "C:\\Temp\\sapnas2\\EXPORT"]; Tuple!(string, SysTime)[] Sorted; foreach(d; FFs[]) { auto dFiles = dirEntries(d, SpanMode.shallow) .filter!(a => a.isDir) .map!(a => tuple(a.name, a.timeCreated)) .array; Sorted ~= dFiles; } Sorted[].sort!((a,b) => a[1] > b[1]) .each!(e => writefln!"%-63s %.20s"(e[0], e[1].to!string)); } -- Biotronic
Dec 15 2017