Converting from DirIterator to string[] without a loop

Dave Chapman via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Sat Jan 14 12:21:43 PST 2017


On Saturday, 14 January 2017 at 01:02:38 UTC, Ali Çehreli wrote:
> 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

Thank you very much.

I had a little trouble getting it working. It was acting as if 
both halves of the "choose" expression were always getting 
executed and the first half was making the contents of "all" 
empty and so the array b was always empty if I used the second 
half of the choose statement. I made a second copy of "all" and 
used it in the second half of the choose statement and then it 
worked.  Like this:

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

   auto b = choose(some_condition,
		  all.filter!(f => (baseName(f.name) == requested_file)).array,
		  all_2.filter!(f => (f.name.endsWith(".html") )).array);


Note that I am really using requested_file instead of 
"file_name.txt" and ".html" instead of ".d" which is different 
than what I told you before just in case that matters.

I am using  Mac  OS X 10.11.5 and dmd version 2.072.2

Thanks again for the help,
Dave




More information about the Digitalmars-d-learn mailing list