2017-08-03 5 views
1

In einigen Sprachen, nachdem man eine Lazy-Sequenz durchläuft, wird es erschöpft. Das ist nicht der Fall mit F#:Warum kann ich nicht zweimal durch die Zeilen eines CSV-Anbieters gehen?

let mySeq = seq [1..5] 

mySeq |> Seq.iter (fun x -> printfn "%A" <| x) 
mySeq |> Seq.iter (fun x -> printfn "%A" <| x) 

1 
2 
3 
4 
5 
1 
2 
3 
4 
5 

aber es sieht aus wie ein nur einmal durch die Zeilen eines CSV-Provider gehen kann:

open FSharp.Data 

[<Literal>] 
let foldr = __SOURCE_DIRECTORY__ + @"\data\" 

[<Literal>] 
let csvPath = foldr + @"AssetInfoFS.csv" 

type AssetsInfo = CsvProvider<Sample=csvPath, 
           HasHeaders=true, 
           ResolutionFolder=csvPath, 
           AssumeMissingValues=false, 
           CacheRows=false> 

let assetInfo = AssetsInfo.Load(csvPath) 
assetInfo.Rows |> Seq.iter (fun x -> printfn "%A" <| x) // Works fine 1st time 
assetInfo.Rows |> Seq.iter (fun x -> printfn "%A" <| x) // 2nd time exception 

Warum ist das passiert?

Antwort

3

Von diesem link auf dem CSV-Parser wird der CSV-Typ-Provider auf dem CSV-Parser erstellt. Der CSV-Parser arbeitet im Streaming-Modus, höchstwahrscheinlich durch Aufruf einer Methode wie File.ReadLines, die eine Ausnahme auslöst, wenn der Enumerator ein zweites Mal aufgezählt wird. Der CSV-Parser verfügt auch über eine Cache-Methode. Versuchen Sie, CacheRows = true zu setzen (oder lassen Sie es aus der Deklaration heraus, da der Standardwert true ist), um dieses Problem zu vermeiden.

1

Der Sequenz-Iterator bleibt dort, wo Sie ihn zeigen; nach der ersten Schleife, das ist das Ende der Sequenz.

Wenn Sie wollen, dass es an den Anfang zurückgeht, müssen Sie es dort einstellen.

Verwandte Themen