I have the following piece of code:
import std.algorithm;
import std.array;
import std.csv;
import std.stdio;
import std.typecons;
import std.getopt;
import std.file;
import std.conv;
struct DataPoint{
double x,y,z;
this(double _x, double _y, double _z){
x = _x;
y = _y;
z = _z;
}
this(char[][] a){
x = to!double(a[0]);
y = to!double(a[1]);
z = to!double(a[2]);
}
DataPoint opBinary(string s)(DataPoint d) if (s == "+"){
auto ret = DataPoint(x + d.x, y + d.y, z + d.z);
return ret;
}
}
void main(string[] args)
{
string csvFile;
try{
getopt(args, std.getopt.config.required, "input|i", &csvFile);
assert(csvFile.isFile);
}
catch(Exception e){
writeln(e.msg);
return;
}
auto file = File(csvFile, "r");
int lineCount = 0;
foreach (string line; lines(file)){
++lineCount;
}
file.close();
file = File(csvFile, "r");
auto aa = file.byLine() // Read lines
.map!split // Split into words
.map!(a => DataPoint(a))
.reduce!((a,b) => a + b);
auto average = DataPoint(aa.x/lineCount, aa.y/lineCount, aa.z/lineCount);
std.stdio.writefln("After reading %d records, "
~"the average is [%.2f, %.2f, %.2f]", lineCount, average.x, average.y, average.z);
}
How can I count the number of lines in the file while iterating over its contents at the same? (in one pass)
It's not very functional, but you can use tee
for inline processing:
int count = 0;
auto x = stdin.byLine.tee!(_ => ++count).map!(/+ ... whatever ... +/);