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

…衆ロ難τιáo~ 提交于 2019-12-04 11:32:48

问题


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}]

回答1:


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:




回答2:


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.




回答3:


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.



来源:https://stackoverflow.com/questions/33075932/how-to-create-a-csv-file-and-write-data-into-in-f

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!