如何为 F# 中的类型生成 CSV reader/writer?
How do I generate a CSV reader/writer for a type in F#?
我正在使用 FSharp.Data
库中的类型提供程序来为我从 Web 服务调用返回的预期 JSON 响应生成类型。当我从示例 JSON 文件生成它们时,这非常有效,例如:
type User = JsonProvider<"data/user.sample.json">
我想做的是生成一些可以读写我在 F# 中定义的类型的 CSV 表示形式的东西。 CsvProvider
似乎不符合要求,就像 JsonProvider
一样,它似乎适用于我 starting 使用 CSV 文件的情况并想要生成一个类型,而我想要一些相反方向的东西。
自己使用 the CsvFile module 滚动这个似乎并不难,但是有更好的方法吗?
是否要自己定义预期的结构JSON?这可以通过 FSharp.Data
轻松实现。下面是获取最近几天黄金价格的示例。
首先定义预期的结构。这里 date
和 price
。然后你就用它来解析你的数据。
type Gold = JsonProvider<"""{ "date":"2015-03-20", "price":1171.75}""">
let goldPrcs = Gold.Parse goldPrcJson
这些是我的示例数据:
let goldPrcJson = """[["2015-03-20",1171.75],["2015-03-19",1164.0],["2015-03-18",1149.0],...]"""
第一个结果:
[
[
"2015-03-20",
1171.75
],
[
"2015-03-19",
1164.0
],
[
"2015-03-18",
1149.0
],
...
]
类似的方法也可以应用于 CSV。
tldr
答案是:不,没有更好的办法
/tldr
总的来说,你有这组数据,你想序列化这组数据,但是又想控制如何序列化数据,而不去控制?
唔?
所以:
只需序列化您拥有的数据。而且,如果您对如何序列化它有任何偏好(json、xml、csv 等),您需要亲自动手并实际决定一些事情,甚至可能需要编写代码来处理一下。
好的,json,xml 是 "easy" 并且或多或少是开箱即用的,直到你遇到一些 "special" 情况并且必须确保它仍然通过添加属性和其他属性来工作。
序列化为 csv 是 OTOH,只不过是将所有数据记录聚合到一个带有分隔符的字符串中,然后将每一行写入文件。
Edit/addendum:
在进一步思考这个问题和主要问题 "what do you actually want to do?" 之后,我认为 "confusion" 可能是类型提供程序是某种超级序列化程序。而不是。
我确实尝试通过添加一些数据来创建 "new" csv 并且工作得很好,但正如你所说你需要先验文件格式,并且该文件格式是 "locked".
你也许可以做类似的事情(我认为无论如何都不应该使用):
#r @"..\packages\FSharp.Data.2.2.0\lib\net40\FSharp.Data.dll"
open FSharp.Data
[<Literal>]
let csvstring = @"Column1;Column2;Column3
Stringinfo;123;20150331"
type SomeCSV = CsvProvider< csvstring, Separators=";", HasHeaders=true >
let csv = SomeCSV.GetSample().Truncate(0)
let rows =
seq
{
yield SomeCSV.Row("colum1", 111, 20150330 )
}
let csvmodded = csv.Append rows
csvmodded.Save(@"c:\temp\csttestmodded.csv")
在再次阅读您所有的评论和原始帖子后,我很确定您想要的是 "serializing"(或 "deserializing")。不是类型提供者。
TypeProviders 用于使用您无法完全控制 format/serialization 的内容(也不是真的,但现在让我们继续使用),尤其是 CSV、XML(没有 XSD) ), JSON, 你不是 "owning" 原来的 "data format" (我猜你称之为 POCO)。
如果您确实拥有 POCO 并想将此数据提供给其他人,则通常不是由类型提供者来处理序列化(但可能是为了在消费端进行反序列化)。
我不确定这次编辑是否阐明了很多(即使对我来说也是如此!;-)
我正在使用 FSharp.Data
库中的类型提供程序来为我从 Web 服务调用返回的预期 JSON 响应生成类型。当我从示例 JSON 文件生成它们时,这非常有效,例如:
type User = JsonProvider<"data/user.sample.json">
我想做的是生成一些可以读写我在 F# 中定义的类型的 CSV 表示形式的东西。 CsvProvider
似乎不符合要求,就像 JsonProvider
一样,它似乎适用于我 starting 使用 CSV 文件的情况并想要生成一个类型,而我想要一些相反方向的东西。
自己使用 the CsvFile module 滚动这个似乎并不难,但是有更好的方法吗?
是否要自己定义预期的结构JSON?这可以通过 FSharp.Data
轻松实现。下面是获取最近几天黄金价格的示例。
首先定义预期的结构。这里 date
和 price
。然后你就用它来解析你的数据。
type Gold = JsonProvider<"""{ "date":"2015-03-20", "price":1171.75}""">
let goldPrcs = Gold.Parse goldPrcJson
这些是我的示例数据:
let goldPrcJson = """[["2015-03-20",1171.75],["2015-03-19",1164.0],["2015-03-18",1149.0],...]"""
第一个结果:
[
[
"2015-03-20",
1171.75
],
[
"2015-03-19",
1164.0
],
[
"2015-03-18",
1149.0
],
...
]
类似的方法也可以应用于 CSV。
tldr 答案是:不,没有更好的办法 /tldr
总的来说,你有这组数据,你想序列化这组数据,但是又想控制如何序列化数据,而不去控制?
唔?
所以:
只需序列化您拥有的数据。而且,如果您对如何序列化它有任何偏好(json、xml、csv 等),您需要亲自动手并实际决定一些事情,甚至可能需要编写代码来处理一下。
好的,json,xml 是 "easy" 并且或多或少是开箱即用的,直到你遇到一些 "special" 情况并且必须确保它仍然通过添加属性和其他属性来工作。
序列化为 csv 是 OTOH,只不过是将所有数据记录聚合到一个带有分隔符的字符串中,然后将每一行写入文件。
Edit/addendum:
在进一步思考这个问题和主要问题 "what do you actually want to do?" 之后,我认为 "confusion" 可能是类型提供程序是某种超级序列化程序。而不是。
我确实尝试通过添加一些数据来创建 "new" csv 并且工作得很好,但正如你所说你需要先验文件格式,并且该文件格式是 "locked".
你也许可以做类似的事情(我认为无论如何都不应该使用):
#r @"..\packages\FSharp.Data.2.2.0\lib\net40\FSharp.Data.dll"
open FSharp.Data
[<Literal>]
let csvstring = @"Column1;Column2;Column3
Stringinfo;123;20150331"
type SomeCSV = CsvProvider< csvstring, Separators=";", HasHeaders=true >
let csv = SomeCSV.GetSample().Truncate(0)
let rows =
seq
{
yield SomeCSV.Row("colum1", 111, 20150330 )
}
let csvmodded = csv.Append rows
csvmodded.Save(@"c:\temp\csttestmodded.csv")
在再次阅读您所有的评论和原始帖子后,我很确定您想要的是 "serializing"(或 "deserializing")。不是类型提供者。
TypeProviders 用于使用您无法完全控制 format/serialization 的内容(也不是真的,但现在让我们继续使用),尤其是 CSV、XML(没有 XSD) ), JSON, 你不是 "owning" 原来的 "data format" (我猜你称之为 POCO)。
如果您确实拥有 POCO 并想将此数据提供给其他人,则通常不是由类型提供者来处理序列化(但可能是为了在消费端进行反序列化)。
我不确定这次编辑是否阐明了很多(即使对我来说也是如此!;-)