www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Can you read the next line while iterating over byLine?

reply John Doe <larivact chello.at> writes:
Let's say you're trying to parse a file format like:

Name
http://example.com
123234

Foo Bar
http://dlang.org
888888

with blocks separated by varying amount of blank lines.

-----
import std.stdio;

void main(string[] args){
     auto range = File("text.txt").byLine();

     foreach( line; range ){
         if (line != ""){
             writeln(line);
             // char[] url = range.???
             // char[] num = range.???
         }
     }
}
-----
How can you read the next line while iterating over a file line 
by line, so that the next iteration uses the line after next? If 
this isn't possible byLine is a design flaw and D should instead 
provide a regular readLine function.

btw: What is this? A forum for a programming language that 
doesn't support code blocks?
Feb 02
next sibling parent Daniel Kozak via Digitalmars-d-learn <digitalmars-d-learn puremagic.com> writes:
There is a readln function, and this is not forum but just web frontend
around mailing list. http://forum.dlang.org/help#about

Dne 2. 2. 2017 7:20 PM napsal u=C5=BEivatel "John Doe via Digitalmars-d-lea=
rn" <
digitalmars-d-learn puremagic.com>:

 Let's say you're trying to parse a file format like:

 Name
 http://example.com
 123234

 Foo Bar
 http://dlang.org
 888888

 with blocks separated by varying amount of blank lines.

 -----
 import std.stdio;

 void main(string[] args){
     auto range =3D File("text.txt").byLine();

     foreach( line; range ){
         if (line !=3D ""){
             writeln(line);
             // char[] url =3D range.???
             // char[] num =3D range.???
         }
     }
 }
 -----
 How can you read the next line while iterating over a file line by line,
 so that the next iteration uses the line after next? If this isn't possib=
le
 byLine is a design flaw and D should instead provide a regular readLine
 function.

 btw: What is this? A forum for a programming language that doesn't suppor=
t
 code blocks?
Feb 02
prev sibling next sibling parent Daniel Kozak via Digitalmars-d-learn <digitalmars-d-learn puremagic.com> writes:
Dne 2. 2. 2017 7:24 PM napsal u=C5=BEivatel "Daniel Kozak" <kozzi11 gmail.c=
om>:

There is a readln function, and this is not forum but just web frontend
around mailing list. http://forum.dlang.org/help#about

https://dlang.org/phobos/std_stdio.html#.File.readln
Feb 02
prev sibling parent reply Jack Stouffer <jack jackstouffer.com> writes:
On Thursday, 2 February 2017 at 18:18:13 UTC, John Doe wrote:
 Let's say you're trying to parse a file format like:

 Name
 http://example.com
 123234

 Foo Bar
 http://dlang.org
 888888

 with blocks separated by varying amount of blank lines.

 -----
 import std.stdio;

 void main(string[] args){
     auto range = File("text.txt").byLine();

     foreach( line; range ){
         if (line != ""){
             writeln(line);
             // char[] url = range.???
             // char[] num = range.???
         }
     }
 }
 -----
 How can you read the next line while iterating over a file line 
 by line, so that the next iteration uses the line after next? 
 If this isn't possible byLine is a design flaw and D should 
 instead provide a regular readLine function.

 btw: What is this? A forum for a programming language that 
 doesn't support code blocks?
If you understand the underlying range interface, the answer becomes clear: import std.stdio; void main(string[] args) { auto range = File("text.txt").byLineCopy(); foreach (line; range) { if (line != "") { writeln(line); range.popFront; char[] url = range.front(); range.popFront; char[] num = range.front(); } } }
Feb 02
next sibling parent reply Daniel Kozak via Digitalmars-d-learn <digitalmars-d-learn puremagic.com> writes:
Even this one could works:

import std.stdio;

void main(string[] args)
{
    auto range = File("text.txt").byLine();

    foreach (line; range)

    {
        if (line != "")
        {
            writeln(line);
            range.popFront;
            char[] url = range.front().dup;
            range.popFront;
            char[] num = range.front().dup
        }
    }
}
Feb 02
parent reply John Doe <larivact chello.at> writes:
On Thursday, 2 February 2017 at 18:58:46 UTC, Daniel Kozak wrote:
 Even this one could works:

 import std.stdio;

 void main(string[] args)
 {
     auto range = File("text.txt").byLine();

     foreach (line; range)

     {
         if (line != "")
         {
             writeln(line);
             range.popFront;
             char[] url = range.front().dup;
             range.popFront;
             char[] num = range.front().dup
         }
     }
 }
Thanks readln is perfect. Since I am calling readln in different places and I always need to remove the newline character I have line=line[0..$-1] all over my code. Is there are better way? unrelated second question: Why is there no split function with a maxsplit parameter?
Feb 02
next sibling parent reply Daniel Kozak via Digitalmars-d-learn <digitalmars-d-learn puremagic.com> writes:
Dne 2. 2. 2017 20:35 napsal u=C5=BEivatel "John Doe via Digitalmars-d-learn=
" <
digitalmars-d-learn puremagic.com>:

On Thursday, 2 February 2017 at 18:58:46 UTC, Daniel Kozak wrote:

 Even this one could works:

 import std.stdio;

 void main(string[] args)
 {
     auto range =3D File("text.txt").byLine();

     foreach (line; range)

     {
         if (line !=3D "")
         {
             writeln(line);
             range.popFront;
             char[] url =3D range.front().dup;
             range.popFront;
             char[] num =3D range.front().dup
         }
     }
 }
Thanks readln is perfect. Since I am calling readln in different places and I always need to remove the newline character I have line=3Dline[0..$-1] al= l over my code. Is there are better way? you can use popBack on readln od trim but it is not more elegant. Maybe open enhancement on issues.dlang.org to phobos to add parametr for not keeping line end char unrelated second question: Why is there no split function with a maxsplit parameter? what is maxsplit parametr, I have never use it od need it?
Feb 02
parent reply John Doe <larivact chello.at> writes:
On Thursday, 2 February 2017 at 20:26:36 UTC, Daniel Kozak wrote:
 Dne 2. 2. 2017 20:35 napsal uživatel "John Doe via 
 Digitalmars-d-learn" < digitalmars-d-learn puremagic.com>:

 On Thursday, 2 February 2017 at 18:58:46 UTC, Daniel Kozak 
 wrote:

[...]
Thanks readln is perfect. Since I am calling readln in different places and I always need to remove the newline character I have line=line[0..$-1] all over my code. Is there are better way? you can use popBack on readln or trim but it is not more elegant. Maybe open enhancement on issues.dlang.org to phobos to add parameter for not keeping line end char unrelated second question: Why is there no split function with a maxsplit parameter? what is maxsplit parameter, I have never use it or need it?
Python's split function has an optional maxsplit parameter to specify the maximum splits that should be done. So that "1,2,3,4,5".split(',', 3) returns ['1', '2', '3', '4,5'].
Feb 02
parent Daniel Kozak via Digitalmars-d-learn <digitalmars-d-learn puremagic.com> writes:
Dne 2.2.2017 v 21:43 John Doe via Digitalmars-d-learn napsal(a):

 On Thursday, 2 February 2017 at 20:26:36 UTC, Daniel Kozak wrote:
 Dne 2. 2. 2017 20:35 napsal uživatel "John Doe via 
 Digitalmars-d-learn" < digitalmars-d-learn puremagic.com>:

 On Thursday, 2 February 2017 at 18:58:46 UTC, Daniel Kozak wrote:

 [...]
Thanks readln is perfect. Since I am calling readln in different places and I always need to remove the newline character I have line=line[0..$-1] all over my code. Is there are better way? you can use popBack on readln or trim but it is not more elegant. Maybe open enhancement on issues.dlang.org to phobos to add parameter for not keeping line end char unrelated second question: Why is there no split function with a maxsplit parameter? what is maxsplit parameter, I have never use it or need it?
Python's split function has an optional maxsplit parameter to specify the maximum splits that should be done. So that "1,2,3,4,5".split(',', 3) returns ['1', '2', '3', '4,5'].
How this is useful? How exactly do you use this (please show some example)? I belive if you show usefull usage it could be easily add to phobos. But to be honest I have never ever need such a thing :)
Feb 02
prev sibling parent reply Ivan Kazmenko <gassa mail.ru> writes:
On Thursday, 2 February 2017 at 19:34:37 UTC, John Doe wrote:
 Thanks readln is perfect. Since I am calling readln in 
 different places and I always need to remove the newline 
 character I have line=line[0..$-1] all over my code. Is there 
 are better way?
"readln.strip" gives the line without the trailing newline character.
Feb 04
parent Mike Parker <aldacron gmail.com> writes:
On Saturday, 4 February 2017 at 08:54:27 UTC, Ivan Kazmenko wrote:
 On Thursday, 2 February 2017 at 19:34:37 UTC, John Doe wrote:
 Thanks readln is perfect. Since I am calling readln in 
 different places and I always need to remove the newline 
 character I have line=line[0..$-1] all over my code. Is there 
 are better way?
"readln.strip" gives the line without the trailing newline character.
Or readln.chomp.
Feb 04
prev sibling parent reply Daniel Kozak via Digitalmars-d-learn <digitalmars-d-learn puremagic.com> writes:
More range aproach, untested written on the fly from mobile phone

import std.stdio : File;
import std.range : chunks;
import.std.algorithm : map, filter, array;

void main()
{
    auto r = File("text.txt").byLine
       .filter!(a=>a.length)
       .chunks(2)
       .map!(a=>[a[0].dup, a[1].dup])
       .array;

    writeln(r);
}
Feb 02
parent =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
On 02/02/2017 11:30 AM, Daniel Kozak via Digitalmars-d-learn wrote:
 More range aproach, untested written on the fly from mobile phone

 import std.stdio : File;
 import std.range : chunks;
 import.std.algorithm : map, filter, array;

 void main()
 {
     auto r = File("text.txt").byLine
        .filter!(a=>a.length)
        .chunks(2)
        .map!(a=>[a[0].dup, a[1].dup])
        .array;

     writeln(r);
 }
I tried that as well but chunks() requires ForwardRange. I wrote a rough sketch of byPairs almost :) on the fly: import std.range; import std.stdio; import std.algorithm; import std.typecons; struct ByPairs(R) if (isInputRange!R) { alias E = ElementType!R; R range; Tuple!(E, E) pair; this (R range) { this.range = range; if (!empty) { prime(); } } void prime() { this.pair[0] = range.front; range.popFront(); this.pair[1] = range.front; range.popFront(); } bool empty() { return range.empty; } auto front() { return pair; } void popFront() { assert(!empty); prime(); } } auto byPairs(R)(R r) { return ByPairs!R(r); } void main() { struct Data { string url; string num; } auto result = File("deneme.txt", "r") .byLineCopy .filter!(line => !line.empty) .byPairs; // Also try appending .map!(t => Data(t[0], t[1])) writefln("%-(%s\n%)", result); } Having to decide on Tuple (or requiring a factory method) is bothersome. It would be great if the programmer need not deal with the intermediate Tuple and just get their Data. So, a 'map' without needing explicit construction like .byPairs.make!Data should somehow work. Or perhaps .mapFromTuple!Data(byPairs) (Not tested.) Ali
Feb 02