Write a sequence of tuples to a csv file f#

本秂侑毒 提交于 2019-12-11 02:57:27

问题


Iam trying to write a sequence of tuples to a csv, but the normal File.WriteAllLines is overloaded by a sequence of tuples.

I have tried therefore to flatten my tuples into a sequence of strings.

Here is my code:-

open System;;
open Microsoft.FSharp.Reflection;;

let tupleToString (t: string * float) = 
        if FSharpType.IsTuple(t.GetType()) 
        then String.Format("{0},{1}", fst t, snd t)
        else "";;

    let testTuple = ("monkey", 15.168);;

    tupleToString(testTuple);;

let testSeqTuple = [("monkey", 15.168); ("donkey", 12.980)];;

let allIsStrings (t:seq<string * float>) = Seq.collect tupleToString t;;

allIsStrings(testSeqTuple);;

When I use "tupleToString" on just one tuple the results are just fine.

However the Seq.collect part of allIsStrings returns the tuples broken down by characters.

I have also tried Seq.choose and Seq.fold, but these simply throw errors.

Can anyone advise as to what function from the sequence module I should be using - or advise on an alternative to File.WriteAllLines that would work on a tuple?


回答1:


You need to use Seq.map to convert all elements of a list to string and then Array.ofSeq to get an array which you can pass to WriteAllLines:

let allIsStrings (t:seq<string * float>) = 
  t |> Seq.map tupleToString
    |> Array.ofSeq

Also, in your tupleToString function, you do not need to use reflection to check that the argument is a tuple. It will always be a tuple, because this is guaranteed by the type system. So you can just write:

let tupleToString (t: string * float) = 
  String.Format("{0},{1}", fst t, snd t)      

You could use reflection if you wanted to make this work for tuples with arbitrary number of parameters (but that is a more advanced topic). The following gets elements of the tuple, converts them all to string and then concatenates them using a comma:

let tupleToString t = 
  if FSharpType.IsTuple(t.GetType()) then
    FSharpValue.GetTupleFields(t)
    |> Array.map string
    |> String.concat ", "
  else failwith "not a tuple!"

// This works with tuples that have any number of elements
tupleToString (1,2,"hi")
tupleToString (1.14,2.24)

// But you can also call it with non-tuple and it fails
tupleToString (new System.Random())



回答2:


The accepted answer is much better, but I've written this now, so there.

let testSeqTuple = [("monkey", 15.168); ("donkey", 12.980)]

let tupleToString t = String.Format("{0},{1}", fst t, snd t)
let tuplesToStrings t = Array.ofSeq (Seq.map tupleToString t)

for s in tuplesToStrings(testSeqTuple) do
    printfn "s=#%s" s


来源:https://stackoverflow.com/questions/13071986/write-a-sequence-of-tuples-to-a-csv-file-f

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