2017-04-24 11 views
6

mam następujący program D, który ma do grupy linii wejściowych do grup wielkości 3.Dlang byLineCopy omijając linie

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

i podane następujące dane wejściowe

Mercury 
Venus 
Earth 
Mars 
Jupiter 
Saturn 
Uranus 
Neptune 
Pluto 

produkuje wyjście.

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

pomijanie linii na granicy każdej iteracji (Mars i Neptun nie są na wyjściu). Co ja robię źle?

+0

hm wydaje się być błędem w funkcji take do mnie. Jeśli chcesz osiągnąć inną funkcję w międzyczasie, aby osiągnąć to samo, użyj '.chunks (3)', która zwraca zakres 3 zakresów długości – WebFreak001

+0

@ WebFreak001 'chunks' nie działa dla mnie. Wygląda na to, że 'byLineCopy' zwraca' InputRange', a 'chunks' spodziewa się' ForwardRange'. –

Odpowiedz

4

stdin.byLineCopycallspopFront, co oznacza, że ​​wielokrotne wywołania do tego na tym samym strumieniu wejściowym będą "pomijać" elementy. Spróbuj utworzyć szereg byLineCopy tylko raz na początku:

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

Nie trzeba sprawdzić eof, jak byLineCopy powinien sobie z tym poradzić.

+0

To rozwiązanie ma zachowanie, którego pragnę. Czy to nie jest błąd w 'byLineCopy'? –

+0

Nie spodziewałbym się utworzenia zakresu mutacji źródła. Zakres "API" mówi, że powinniśmy nazwać 'front', następnie' popFront'. Nie działa to jednak w przypadku 'stdin', gdzie trzeba je przesuwać, aby uzyskać dostęp do' przodu' po raz pierwszy, co oznacza, że ​​potrzebujemy początkowego 'popFront', aby wszystko działało. Można to nazwać błędem, nazywam to niefortunną rzeczywistością :) – rcorre

1

Brzmi jak chcesz std.range.chunks, w połączeniu z std.range.enumerate zachowania indeksów:

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

Zauważ, że .array jest potrzebna jako chunks wymaga ForwardRange podczas stdin.byLineCopy jest InputRange.

+1

Twoje rozwiązanie działa. Ale chciałbym uniknąć nakładu na utrzymanie całego wejścia w tablicy (uważam, że właśnie to robi '.array'), kiedy potrzebuję tylko małej jego części w pamięci na raz. Jest to jeden z powodów, dla których w pierwszej kolejności użyłem polecenia "take" zamiast "chunk". –

+0

Rozumiem. Myślę, że teraz dostałem lepszą odpowiedź. Usuwam ten, jeśli nie doda żadnej wartości. – rcorre