www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - How to force evaluation of range?

reply Taylor Hillegeist <taylorh140 gmail.com> writes:
So I have this code and I have to add the element
.each!(a => a.each!("a"));
to the end in order for it to evaluate the range completely and 
act like I expect it too. Is there a  better thing to put in the 
place of
.each!(a => a.each!("a"));?

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

void main(string[] Args){

     assert(Args.length>1,"Need a path to source files");
     assert(Args[1].isValidPath,"Path given is not Valid!");

     dirEntries(Args[1], SpanMode.depth)
         .filter!(f => f.name.endsWith(".c",".h"))
         .tee!(a => writeln("\n",a,"\n\t","=".repeat(80).join))
         .map!(a => a
             .File("r")
             .byLine
             .enumerate
             .filter!( l => l.value.byGrapheme.walkLength > 80)
             .tee!(a => writeln("Line: ",a.index,"\t",a.value))
          ).each!(a => a.each!("a")); //Force evaluation of every 
item

}
Feb 12 2016
next sibling parent Messenger <dont shoot.me> writes:
On Friday, 12 February 2016 at 20:43:24 UTC, Taylor Hillegeist 
wrote:
 So I have this code and I have to add the element
 .each!(a => a.each!("a"));
 to the end in order for it to evaluate the range completely and 
 act like I expect it too. Is there a  better thing to put in 
 the place of
 .each!(a => a.each!("a"));?

 [...]

     dirEntries(Args[1], SpanMode.depth)
         .filter!(f => f.name.endsWith(".c",".h"))
         .tee!(a => writeln("\n",a,"\n\t","=".repeat(80).join))
         .map!(a => a
             .File("r")
             .byLine
             .enumerate
             .filter!( l => l.value.byGrapheme.walkLength > 80)
             .tee!(a => writeln("Line: ",a.index,"\t",a.value))
          ).each!(a => a.each!("a")); //Force evaluation of 
 every item

 }
Have you tried .array? I *think* it's the commonly used way to flatten a lazy range.
Feb 12 2016
prev sibling next sibling parent reply Nicholas Wilson <iamthewilsonator hotmail.com> writes:
On Friday, 12 February 2016 at 20:43:24 UTC, Taylor Hillegeist 
wrote:
 So I have this code and I have to add the element
 .each!(a => a.each!("a"));
 to the end in order for it to evaluate the range completely and 
 act like I expect it too. Is there a  better thing to put in 
 the place of
 .each!(a => a.each!("a"));?

 [...]
If you need the value that a range returns (i.e. the range performs "computation") then use .array If you just want the range evaluated use walkLength
Feb 12 2016
parent Xinok <xinok live.com> writes:
On Saturday, 13 February 2016 at 01:11:53 UTC, Nicholas Wilson 
wrote:
 ...

 If you just want the range evaluated use walkLength
It might work in this case, but in general this won't work for any range which defines .length as a member. In that case, walkLength will simply return .length of that range.
Feb 12 2016
prev sibling parent reply Xinok <xinok live.com> writes:
On Friday, 12 February 2016 at 20:43:24 UTC, Taylor Hillegeist 
wrote:
 So I have this code and I have to add the element
 .each!(a => a.each!("a"));
 to the end in order for it to evaluate the range completely and 
 act like I expect it too. Is there a  better thing to put in 
 the place of
 .each!(a => a.each!("a"));?

 ...
The following combination might work: .joiner.each;
Feb 12 2016
parent reply cym13 <cpicard openmailbox.org> writes:
On Saturday, 13 February 2016 at 02:17:17 UTC, Xinok wrote:
 On Friday, 12 February 2016 at 20:43:24 UTC, Taylor Hillegeist 
 wrote:
 So I have this code and I have to add the element
 .each!(a => a.each!("a"));
 to the end in order for it to evaluate the range completely 
 and act like I expect it too. Is there a  better thing to put 
 in the place of
 .each!(a => a.each!("a"));?

 ...
The following combination might work: .joiner.each;
Why not just .each; ?
Feb 12 2016
parent Xinok <xinok live.com> writes:
On Saturday, 13 February 2016 at 03:16:09 UTC, cym13 wrote:
 On Saturday, 13 February 2016 at 02:17:17 UTC, Xinok wrote:
 On Friday, 12 February 2016 at 20:43:24 UTC, Taylor Hillegeist 
 wrote:
 So I have this code and I have to add the element
 .each!(a => a.each!("a"));
 to the end in order for it to evaluate the range completely 
 and act like I expect it too. Is there a  better thing to put 
 in the place of
 .each!(a => a.each!("a"));?

 ...
The following combination might work: .joiner.each;
Why not just .each; ?
The thing he's trying to iterate over is a range of ranges. A single .each will only iterate over the outermost range so you need .joiner first to "flatten" the range, then you can use .each on that result.
Feb 12 2016