将string和List混合成List



我有这个函数可以写入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"]

有了这个,你的大部分代码(几乎(都能工作!唯一的变化是您需要使transposestring 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 ";")

最新更新