我试图将一系列元组写入csv,但正常的File.WriteAllLines被一系列元组重载。
因此我试图将我的元组变成一系列字符串。
这是我的代码: -
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);;
当我使用&#34; tupleToString&#34;只有一个元组,结果就好了。
然而allIsStrings的Seq.collect部分返回按字符分解的元组。
我也试过Seq.choose和Seq.fold,但这些只是抛出错误。
任何人都可以建议我应该使用序列模块中的哪些函数 - 或者建议使用可以在元组上工作的File.WriteAllLines的替代方法吗?
答案 0 :(得分:10)
您需要使用Seq.map
将列表的所有元素转换为string
,然后转换为Array.ofSeq
以获取可传递给WriteAllLines
的数组:
let allIsStrings (t:seq<string * float>) =
t |> Seq.map tupleToString
|> Array.ofSeq
此外,在tupleToString
函数中,您不需要使用反射来检查参数是否为元组。它永远是一个元组,因为这是由类型系统保证的。所以你可以写:
let tupleToString (t: string * float) =
String.Format("{0},{1}", fst t, snd t)
如果您希望使用任意数量的参数(但这是一个更高级的主题)使元组工作,可以使用反射。以下获取元组的元素,将它们全部转换为字符串,然后使用逗号连接它们:
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())
答案 1 :(得分:5)
接受的答案要好得多,但我现在写了这个,所以那里。
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