如何将CsvHelper.CsvWriter与F#选项类型一起使用? [英] How do you use CsvHelper.CsvWriter with F# option types?

查看:63
本文介绍了如何将CsvHelper.CsvWriter与F#选项类型一起使用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用.Net CsvHelper库将F#记录集合保存到csv文件中.问题在于选项类型没有正确转换为字符串.

I am trying to save an F# record collection to a csv file using the .Net CsvHelper library. The problem is that option types are not being converted to string correctly.

#r "nuget: CsvHelper"

open System.IO 
open System.Globalization
open CsvHelper

type Record = { X : string; Y : float option }

let writeString x =
    use writer = new StringWriter()
    use csv = new CsvWriter(writer, CultureInfo.InvariantCulture)
    csv.WriteRecords(x)
    writer.ToString()

[{ X = "hi"; Y = Some 1.00}
 { X = "bye"; Y = None }]
|> writeString

我期望此处第二个数据行中的第二个字段为空值(或CsvProvider可以理解的任何其他 nan 值).而是CsvHelper将 None 值转换为 0 .

I expect a blank value (or any other nan value that CsvProvider will understand) for the second field in the second data row here. Instead, CsvHelper is converting the None value to 0.

val it : string = "X,Value
hi,1
bye,0
"

我知道, FSharp.Data.CsvProvider 可以让我将此简单记录转换为可以保存的 CsvFile.Row .但是,当您有许多字段时,这是一个糟糕的解决方案,因为很难保持 CsvFile.Row 中字段的顺序直(想象50个浮点字段).我希望能自动转换记录字段的解决方案.

I am aware that FSharp.Data.CsvProvider would let me convert this simple record to a CsvFile.Row that can be saved. But that's a poor solution when you have many fields because it is hard to keep the order of the fields in the CsvFile.Row straight (imagine 50 float fields). I'd prefer a solution in which the record fields are converted automatically.

推荐答案

CsvHelper中似乎没有对F#的内置支持,因此您可能必须编写自己的

It looks like there's no built-in support for F# in CsvHelper, so you probably have to write your own type converter to handle options. Here's a quick one I whipped up:

open System.IO 
open System.Globalization
open CsvHelper
open CsvHelper.TypeConversion

type OptionConverter<'T>() =
    inherit DefaultTypeConverter()
    override __.ConvertToString(value, row, memberMapData) =
        match value :?> Option<'T> with
            | None -> ""
            | Some x -> base.ConvertToString(x, row, memberMapData)

type Record = { X : string; Y : float option }

let writeString x =
    use writer = new StringWriter()
    use csv = new CsvWriter(writer, CultureInfo.InvariantCulture)
    csv.Context.TypeConverterCache.AddConverter<Option<float>>(OptionConverter<float>())
    csv.WriteRecords(x)
    writer.ToString()

[<EntryPoint>] 
let main _ =
    [{ X = "hi"; Y = Some 1.00}
     { X = "bye"; Y = None }]
        |> writeString
        |> printfn "%s"
    0

输出为:

X,Y
hi,1
bye,

FWIW,有一些更易于从F#使用的CSV库,例如

FWIW, there are CSV libraries that are easier to use from F#, such as the FSharp.Data CSV provider.

这篇关于如何将CsvHelper.CsvWriter与F#选项类型一起使用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆