How to create a CSV file and write data into in f#

2019-03-20 11:41发布

How can i can i create a csv file in f sharp and write the following record type in it?

    type test = { G:array<double>; P:array<double>; GG:array<double>; PP:array<double> } 

    let table = [for x in 0..(Un0.Length - 1) -> 
        let b = Un0.[x] in 
        if b=0.0 then {G=0.0; P=0.0; GG=0.0; PP=0.0}
        else {G=G_0.[x]/b; P=P0.[x]/b; GG=G0.[x]/b; PP=PP0.[x]/b}]

标签: f# f#-data
3条回答
家丑人穷心不美
2楼-- · 2019-03-20 12:21

To record in .csv is not necessary to use F# Data.

I changed the definition of test and added some values so that you can compile:

type test = { G:double; P:double; GG:double; PP:double }
            override this.ToString() = 
                sprintf "%f;%f;%f;%f\n" this.G this.P this.GG this.PP

let G_0  =  [|(0.0)..(10.0)|]
let Un0  =  [|(1.0)..(11.0)|]
let P0   =  [|(2.0)..(12.0)|]
let G0   =  [|(3.0)..(13.0)|]
let PP0  =  [|(4.0)..(14.0)|]

let table = [for x in 0..(Un0.Length - 1) -> 
                let b = Un0.[x] 
                if b=0.0 then {G=0.0; P=0.0; GG=0.0; PP=0.0}
                else {G=G_0.[x]/b; P=P0.[x]/b; GG=G0.[x]/b; PP=PP0.[x]/b}]

let wr = new System.IO.StreamWriter("Csv.csv")
table |> List.map(string) |> String.concat("") |> wr.Write
wr.Close()

Result:

enter image description here

查看更多
小情绪 Triste *
3楼-- · 2019-03-20 12:25

The CSV type provider from FSharp.Data is primarily known and used for reading CSVs (as the name suggests), but it's also quite capable of writing CSVs as well.

All you need to do is to define the type, either by providing a sample .CSV file

let titanic2 = CsvProvider<"../data/Titanic.csv", Schema="Fare=float,PClass->Passenger Class">.GetSample()

or by directly defining the schema

type MyCsvType = CsvProvider<Schema = "A (int), B (string), C (date option)", HasHeaders=false>

then you can create a record object and populate it (in a type-safe way!)

// you can build the rows themselves
let myCsv = new MyCsvType( [ MyCsvType.Row(1, "a", None)
                             MyCsvType.Row(2, "B", Some DateTime.Now) ])

// or, for your scenario, you probably want to define a conversion function
// from your record type to the CSV provider's type
let buildRowFromObject obj = MyCsvType.Row(obj.A, obj.B, obj.C)

let buildTableFromObjects = (Seq.map buildRowFromObject) >> Seq.toList >> MyCsvType

let myCsv = someSequenceOfObjects |> buildTableFromObjects

and finally, just call

myCsv.SaveToString()

to get the output in CSV format.

查看更多
爷、活的狠高调
4楼-- · 2019-03-20 12:28

This is not exactly answer to your question, but it is similar and could be handy

How to EDIT csv file with f# CSV Type Provider

Solution:

#r "..\packages\FSharp.Data.2.3.3\lib\\net40\FSharp.Data.dll"
open System.IO
open FSharp.Data

type CsvTest = CsvProvider<"""C:\Users\User\Desktop\sample.csv""">
let textReader = File.OpenRead("""C:\Users\User\Desktop\sample.csv""")// need to use TextReader
let csvTest = CsvTest.Load(textReader)
let modified = csvTest.Append [CsvTest.Row(3,"bum") ]// add row to csv
textReader.Close()// closing file before edit...
modified.Save   """C:\Users\User\Desktop\sample.csv""" //save it

You may need to Reset Interactive Session (if you work with fsx)

Explanation:

Straightforward file loading like this:

let csvTest = CsvTest.Load("""C:\Users\User\Desktop\sample.csv""")

Does not work. If you try it you will get error:

System.IO.IOException: 'The process cannot access the file 'C:\Users\User\Desktop\sample.csv' because it is being used by another process.'

So I use TextReader, that can be closed..

Maybe there is easiest solution, but I didn't find any.

查看更多
登录 后发表回答