为什么我不能通过CSV提供商的行进行两次?

时间:2017-08-03 18:17:27

标签: f# sequence type-providers

在某些语言中,经过一个懒惰的序列,它会变得疲惫不堪。 F#

的情况并非如此
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

但是,看起来只能通过CSV提供商的行进行一次:

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

为什么会这样?

2 个答案:

答案 0 :(得分:3)

通过CSV分析器上的link,CSV类型提供程序构建在CSV分析程序之上。 CSV解析器以流模式工作,最有可能通过调用File.ReadLines之类的方法,如果第二次枚举枚举器,则会抛出异常。 CSV解析器还具有Cache方法。尝试设置CacheRows = true(或将其保留在声明之外,因为它的默认值为true)以避免此问题

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

答案 1 :(得分:1)

序列迭代器保持在你指向它的位置;在第一个循环之后,即序列的结束。

如果你想要它回到开头,你必须在那里设置它。