我有这个函数可以写入csv文件。csv文件的输出应该是这样的。
title(string) body(string) images(list) variations(list)
ipsum1 lorem1 img1 variation1
empty empty img2 variation2
empty empty img3 variation3
我尝试使用的函数是这样的。
let col1 = ["title"; title]
let col2 = ["body"; stringedBody]
let col3 = ["images", images] //LIST
let col4 = ["allVariations",allVariations] //LIST
let cols = [col1; col2; col3; col4; ] //*col3 & 4 gives all elements must be of the same type as the first element, witch here is 'string' . This element has type 'string * string list*'
let transpose(xs: string list list) : string list list =
[0 .. xs.[0].Length - 1] |> List.map (fun i ->
xs |> List.rev |> List.fold (fun acc col -> col.[i] :: acc) []
)
let stringify_rows(xs: string list list) : string list =
xs |> List.map (fun row -> System.String.Join(";", row))
System.IO.File.WriteAllLines("\test.csv", cols |> transpose |> stringify_rows)
但问题似乎出在第3列和第4列,我还试图创建一个图像阵列
let mutable img = [|images|]
但这也给了我一个类似的错误。
提前谢谢。
如果你想以统一的方式处理F#中的一个事物列表,那么列表中的所有事物都需要是相同的类型。你的例子并非如此。在某些情况下(当每行的值不同时(,您使用字符串列表,但在其他情况下(所有行的值相同时(,仅使用单个字符串。
修复逻辑的最好方法是想出一个统一的表示法。我认为最简单的选择是使用string option
值的列表。然后,可以使用Some "str"
作为值,使用None
作为缺失值:
let col1 = [Some "title"; Some "lorem"; None; None]
let col2 = [Some "body"; Some "ipsum"; None; None]
let col3 = [Some "images"; Some "img1"; Some "img2"; Some "img3"]
let col4 = [Some "allVariations"; Some "var1"; Some "var2"; Some "var3"]
有了这个,你的大部分代码(几乎(都能工作!唯一的变化是您需要使transpose
与string option
兼容。您可以将注释更改为'a list list
:
let transpose(xs: 'a list list) : 'a list list =
[0 .. xs.[0].Length - 1] |> List.map (fun i ->
xs |> List.rev |> List.fold (fun acc col -> col.[i] :: acc) []
)
我还更改了stringify_rows
,添加了一个空字符串作为缺失值的默认值:
let stringify_rows(xs: string option list list) : string list =
xs |> List.map (fun row ->
row |> List.map (Option.defaultValue "") |> String.concat ";")