2017-01-12 6 views
1

私は次のコードを持っています。同じで、その内容を反復しながら、Dで機能的に行数を数え、演算を行うには?

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); 
} 

は、どのように私は、ファイル内の行数を数えることができますか? (1回のパスで)

+0

各ライン上の簡単なforeachの変数をインクリメントすることは、おそらく最も簡単な方法ですが。ほとんどのコードを見てください。 foreachループの中であなたのアルゴリズム関数を使用して、あなたは良いことになるはずです – Bauss

答えて

4

それは非常に機能していないのですが、あなたは、インライン処理のためteeを使用することができます。

int count = 0; 
auto x = stdin.byLine.tee!(_ => ++count).map!(/+ ... whatever ... +/); 
1

ので、同様にあなたは、単語に分割する前に、アイデンティティインクリメント機能をマップすることができます:

file.byLine() 
    .map!((a){ lineCount++; return a; }) 
    ... 

また、あなたが原因の奇妙なパラメータの順序に、代わりにreducefoldを使用してになります後者は開始値を使用しています。

関連する問題