reading file byLine
H. S. Teoh via Digitalmars-d-learn
digitalmars-d-learn at puremagic.com
Thu Sep 3 16:50:55 PDT 2015
On Thu, Sep 03, 2015 at 11:38:54PM +0000, Namal via Digitalmars-d-learn wrote:
> On Thursday, 3 September 2015 at 23:31:27 UTC, Jordan Wilson wrote:
> >On Thursday, 3 September 2015 at 23:28:37 UTC, Namal wrote:
> >>On Thursday, 3 September 2015 at 23:25:52 UTC, Jordan Wilson wrote:
> >>>And also:
> >>>import std.algorithm
> >>>
> >>>Sorry, I should have taken the time to answer properly and fully.
> >>
> >>import std.file, std.stdio, std.string, std.conv, std.algorithm;
> >>
> >>void main(){
> >>
> >> auto file = File("text.txt");
> >> auto numbers = file.byLine()
> >> .map!(a => a.split)
> >> .map!(a => map!(a => to!int(a))(a))
> >> .array();
> >>
> >> writeln(numbers);
> >>}
> >>
> >>Error: no property 'array' for type 'MapResult!(__lambda2,
> >>MapResult!(__lambda1, ByLine!(char, char)))'
> >>
> >>Still an error.
> >
> >import std.array
>
> Thx, finaly, this is so much harder to understand than c++ iostream
I would have written it slightly differently, to emphasize what exactly
is going on:
auto numbers = File("text.txt") // read file
.byLine() // line by line
.map!(a => a.split // split each line into words
.map!(a => to!int(a)) // convert each word into int
.array) // collect the ints into an array (per line)
.array; // collect all line arrays into one big array
This is the functional way of doing it, of course. If you're more
comfortable with the C++-style imperative approach, you could do this
instead:
auto file = File("text.txt");
int[][] numbers;
foreach (line; file.byLine) {
auto words = line.split;
int[] lineNums;
foreach (word; words) {
lineNums ~= word.to!int;
}
numbers ~= lineNums;
}
The functional approach is admittedly a bit harder to understand at
first, but it's extremely powerful because it processes everything in a
pipeline, and you can compose operators on the pipeline easily,
rearrange the sequence of operations, etc..
In the imperative nested-loop approach, things quickly get out of hand
once the loop is nested about 2-3 levels deep. A nested loop of 6-7
levels deep would be basically impossible to understand, maintain, or
debug without major refactoring into smaller functions. (In fact,
split() is a library-provided function that basically encapsulates one
of those nested loops.) But if you take the refactoring to its logical
conclusion, you'll eventually end up with a whole bunch of tiny
functions with only a single loop each, each calling the next function
in a chain -- in other words, you arrive at the functional pipeline
approach. :-)
D allows you to do it either way, but the superior approach IMO is to
learn the functional pipeline approach.
T
--
Life is too short to run proprietary software. -- Bdale Garbee
More information about the Digitalmars-d-learn
mailing list