byLine(n)?

Jonathan M Davis via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Sun Jun 11 00:53:34 PDT 2017


On Sunday, June 11, 2017 06:28:18 Stanislav Blinov via Digitalmars-d-learn 
wrote:
> On Sunday, 11 June 2017 at 05:36:08 UTC, helxi wrote:
> > I was writing a program that reads and prints the first nth
> > lines to the stdout:
> >
> > import std.stdio;
> >
> > void main(string[] args)
> > {
> >
> >     import std.algorithm, std.range;
> >     import std.conv;
> >     stdin.byLine.take(args[1].to!ulong).each!writeln;
> >
> > }
> >
> > As far as I understand the stdin.byLine.take(args[1].to!ulong)
> > part reads all the lines written in stdin.
> > What if I want to make byLine read only and only first nth line?
> >
> > stdin.byLine(args[1].to!ulong).each!writeln;
> >
> > Obviously the code above won't work. Is there any efficient
> > workaround?
>
> You need only the nth line? Then you'd need to `drop` the
> preceding ones:
>
> void main(string[] args) {
>      import std.algorithm, std.range, std.stdio, std.conv;
>      stdin.byLine.drop(args[1].to!int-1).front.writeln;
> }
>
> Or if you need every nth line, combine `drop` and `stride`:
>
> void main(string[] args) {
>      import std.algorithm, std.range, std.stdio, std.conv;
>      auto step = args[1].to!int;
>      stdin.byLine.drop(step-1).stride(step).each!writeln;
> }

Another thing to note is that byLine reuses its buffer. So, every time
popFront is called on it, the contents of the buffer are replaced. So, if
any code keeps that dynamic array around without (i)duping it, then you get
buggy code. So, whether byLine's reuse of the buffer is a nice efficiency
boost (since it avoids reallocating the buffer) or a bug waiting to happen
depends on what your code is doing. I think that there's a decent chance
that byLine will work properly in this case, but I don't know for sure. If
it _is_ a problem that byLine reuses its buffer, then use byLineCopy
instead.

Personally, I'd be leery of using byLine outside of foreach loops because of
the buffer reuse, but some range-based code _can_ use it correctly. You just
need to be aware of the issue so that you switch to byLineCopy or (i)dup the
buffers manually if byLine's behavior is not what's correct for your code.

- Jonathan M Davis



More information about the Digitalmars-d-learn mailing list