问题
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