Iai*_*n S 1 sorting directory d date
我试图获取目录的内容,按修改时间排序.我不认为有一种方法可以在dirEntries调用中直接执行此操作,因此我的策略是收集所有文件时间和名称,然后按锁定步骤对两个数组进行排序.
问题1:我无法弄清楚如何将a sysTime转换为整数.
问题2:我无法弄清楚如何并行排序两个数组.
与D中的每个问题一样,不可能找到如何做到这一点:(
这是我的代码:
import std.file;
import std.stdio : writeln;
import std.algorithm;
import std.datetime;
void main() {
string[] myFiles;
double[] myTimes;
foreach (DirEntry e; dirEntries("c:/users/istaffel/", SpanMode.shallow)) {
// calculate unix time (this doesn't work)
auto dur = (cast(Date)e.timeLastModified) - Date(1970,1,1);
// store modified time and filename
myTimes ~= dur.seconds;
myFiles ~= e.name;
}
// now find a way to sort myFiles in order of ascending myTimes...
// print in order
for (int i = 0; i < myTimes.length; i++) {
writeln(myTimes[i], " ", myFiles[i]);
}
}
Run Code Online (Sandbox Code Playgroud)
一般来说,除非你与C交互,否则我建议转换SysTime为一个整数值是一个坏主意(并将其转换double为更糟糕的).但是如果你真的需要将它转换为time_t你似乎正在做的事情,那么只需使用SysTime的toUnixTime函数:
auto timeT = e.timeLastModified.toUnixTime();
Run Code Online (Sandbox Code Playgroud)
做你想做的事的最简单的解决方案就是这样
import std.algorithm;
import std.array;
import std.datetime;
import std.file;
import std.stdio;
void main(string[] args)
{
auto directoryToList = args[1];
auto files = array(dirEntries(directoryToList, SpanMode.shallow));
sort!"a.timeLastModified < b.timeLastModified"(files);
foreach(file; files)
writefln("%s %s", file.timeLastModified, file.name);
}
Run Code Online (Sandbox Code Playgroud)
如果你真的想要一个time_t,那就去做吧file.timeLastModified.toUnixTime().
dirEntries返回一个范围,所以你可以迭代它并直接对它进行操作,但是为了对它进行排序,你需要一个随机访问范围(结果dirEntries不是,因为它懒惰地访问文件).因此,您可以使用它std.array.array从中创建一个数组,然后对其进行排序.sort接受一个谓词(可以是一个转换为带有std.functional的函数的字符串,一个lambda文字,一个委托,一个函数指针,或者用你正在排序的两个参数调用的任何东西 - 在这种情况下我使用了一个字符串,在下面的例子中,我使用lambda文字map).
如果你正在处理大量的文件,并希望最大限度地减少使用的内存量(因为DirEntry有几个成员变量,所以如果所有你关心的话,它们的数组都会占用比你想要的更多的内存是文件的名称和修改时间,然后它变得更有趣,但它仍然是非常可行的.
import std.algorithm;
import std.array;
import std.datetime;
import std.file;
import std.stdio;
import std.typecons;
void main(string[] args)
{
auto directoryToList = args[1];
auto files = dirEntries(directoryToList, SpanMode.shallow);
auto pairs = array(map!(a => tuple(a.timeLastModified, a.name))(files));
sort!"a[0] < b[0]"(pairs);
foreach(pair; pairs)
writefln("%s: %s", pair[0], pair[1]);
}
Run Code Online (Sandbox Code Playgroud)
再说一遍,如果你真的想要一个time_t,那就去做吧pair[0].toUnixTime().
这最终会创建一个包含时间和名称的元组数组,然后只使用时间进行排序.
如果你对范围不是很熟悉,那么我建议你从一本关于D.D标准库的在线书籍中读到这一章,这个标准库使用的范围相当大,这可能就是为什么你觉得你很难搞清楚如何在D. Ranges做一些非常强大的概念,但他们确实需要一些时间来适应.