2017-04-24 53 views
6

我有應該組輸入線成大小3.Dlang byLineCopy跳過線

import std.stdio; 
import std.range; 
import std.array; 

void main() 
{ 
    while (!stdin.eof) { 
    auto currentBlock = array(take(stdin.byLineCopy, 3)); 

    foreach (i, e; currentBlock) { 
     writefln("%d) %s", i, e); 
    } 
    } 
} 

的基團並給予下述的輸入

Mercury 
Venus 
Earth 
Mars 
Jupiter 
Saturn 
Uranus 
Neptune 
Pluto 

它產生的輸出以下d程序。

0) Mercury 
1) Venus 
2) Earth 
0) Jupiter 
1) Saturn 
2) Uranus 
0) Pluto 

在每次迭代時在邊界上跳過線(火星和海王星不在輸出中)。我究竟做錯了什麼?

+0

對於我來說,hm好像是一個bug函數。如果你想同時使用其他函數來實現同樣的功能,可以使用'.chunks(3)',它返回3個長度範圍的範圍。 – WebFreak001

+0

@ WebFreak001'chunks'不適用於我。看來'byLineCopy'返回一個'InputRange','chunks'需要一個'ForwardRange'。 –

回答

4

stdin.byLineCopycallspopFront,這意味着在同一個輸入流上對此重複調用將會「跳過」元素。嘗試在開始創建byLineCopy範圍只有一次:

void main() 
{ 
    auto r = stdin.byLineCopy; 
    while (!r.empty) { 
     foreach (i, e; r.take(3).enumerate) { 
      writefln("%d) %s", i, e); 
     } 
    } 
} 

你並不需要檢查eof,爲byLineCopy應該處理。

+0

該解決方案具有我想要的行爲。這不是'byLineCopy'中的錯誤嗎? –

+0

我不希望創建一個範圍來改變源。範圍'API'表示我們應該調用'front',然後調用'popFront'。然而,這對於'stdin'來說並不是很有效,在那裏你必須首先進入'front',這意味着我們需要一個初始的'popFront'來完成事情。你可以稱它爲一個錯誤,我稱之爲不幸的現實:) – rcorre

1

聽起來像你想std.range.chunks,與std.range.enumerate結合保留指數:

void main() 
{ 
    foreach (i, chunk; stdin.byLineCopy.array.chunks(3).enumerate) { 
     writefln("%s", chunk); 
    } 
} 

注意.array需要爲chunks需要ForwardRangestdin.byLineCopyInputRange

+1

您的解決方案有效。但是,我希望避免將整個輸入保存在數組中的開銷(我相信這就是'.array'所做的),因爲我一次只需要一小部分內存。這就是爲什麼我首先使用'take'而不是'chunk'的原因之一。 –

+0

我明白了。我想我現在已經提供了一個更好的答案。如果它沒有添加任何值,我會刪除這一個。 – rcorre