0

I want to use the following console program to get the type information (not the data) of Csv type provider. The file name will be passed as a command line argument. However, it seems the CsvProvider<> only accept constant literal.

Is there a way to workaround it? Or is it possible to do it using F# script? Or can F# compiler service help?

Or is there any other project does this?

open FSharp.Data
open Microsoft.FSharp.Collections
open System

[<Literal>] 
let fn = """C:\...\myfile.csv""" // Want to dynamically set the fn from arguments

[<EntryPoint>]
let main argv = 
    let myFile = CsvProvider<fn>.GetSample()
    // The following doesn't work
    let fn = argv.[0]
    let myFile = CsvProvider<fn>.GetSample()

    // code to get type information of myFile
4

2 回答 2

4

我认为您可能误解了 CSV 类型提供程序的目的 - 这个想法是您在编译时有一个具有代表性的数据样本(并且可以使用它来指导类型推断)。在运行时,您只需给它(可能是不同的)具有相同格式的文件。这为您提供了一种处理已知格式文件的好方法。

如果您想解析任意 CSV 文件(具有不同的标题等),那么 CSV 类型提供程序将无济于事。但是,您仍然可以使用CsvFileF# Data 中的类型,它提供了一个简单的 CSV 解析器。文档中的示例:

// Download the stock prices
let msft = CsvFile.Load("http://ichart.finance.yahoo.com/table.csv?s=MSFT")

// Print the prices in the HLOC format
for row in msft.Rows do
  printfn "HLOC: (%s, %s, %s)" (row.GetColumn "High") 
     (row.GetColumn "Low") (row.GetColumn "Date")

在这里,您放弃了漂亮的静态类型,但您可以加载任何格式的文件(然后动态查看文件中可用的列)。

于 2015-06-03T04:59:43.467 回答
1

Tomas 建议,可以使用以下 F#-Data CSV 提供程序函数来解决该问题。

let data = CsvFile.Load(....)
let inferredProperties =
    // InferColumnTypes : inferRows:int 
    // * missingValues:string [] 
    // * cultureInfo:CultureInfo 
    // * schema:string 
    // * assumeMissingValues:bool 
    // * preferOptionals:bool 
    // * ?unitsOfMeasureProvider:IUnitsOfMeasureProvider 
    // -> PrimitiveInferedProperty list
    data.InferColumnTypes(10000, [|""|], CultureInfo.InvariantCulture, "", false, true)

不确定应该使用什么参数。但上述设置似乎工作正常。

于 2015-06-04T06:31:00.477 回答