Converting from DirIterator to string[] without a loop

Ali Çehreli via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Fri Jan 13 17:02:38 PST 2017


On 01/13/2017 04:29 PM, Dave Chapman wrote:

 > When I use auto and print out the type of b it is  something like
 > args.main.FilterResult!(__lambda2, DirIterator).FilterResult and for the
 > "if" version of
 > b and args.main.FilterResult!(__lambda3, DirIterator).FilterResult for
 > the "else" version
 > so they are really different types.

The solution for that case is to use std.range.choose:

     auto b = choose(some_condition,
                     all.filter!(f => baseName(f.name) == "file_name.txt"),
                     all.filter!(f => (f.name.endsWith(".d") )));

but I get the following error with DMD64 D Compiler v2.072.1:

   Error: no property '__postblit' for type 'FilterResult!(__lambda2, 
DirIterator)', did you mean '__xpostblit'?

So, I put .array after both expressions below.

The idiomatic way for what you're looking for is std.array.array (which 
is also exposed through std.range):

import std.stdio;
import std.file;
import std.algorithm;
import std.range;
import std.path;

void main(string[] args) {
     bool some_condition = (args.length > 1) && (args[1] == "foo");

     auto all = dirEntries("directory", SpanMode.shallow);

     auto b = choose(some_condition,
                     all.filter!(f => baseName(f.name) == 
"file_name.txt").array,
                     all.filter!(f => (f.name.endsWith(".d") )).array);

     writeln(b);
}

However, in most cases keeping 'b' as a lazy algorithm is sufficient. 
Unless you really need an array e.g. for sorting, you can use 
std.algorithm.each (or map, etc.). (Not applicable in this case because 
of the error I mentioned above.)

Ali



More information about the Digitalmars-d-learn mailing list