Reputation: 2277
I have an array with multiple lists inside and want to write the values to an CSV unfortunately I cannot figure out how to write the Array.mapi.
Any ideas?
let temp = [|title;body;ordinariePris;extraPris;inkopPris;images;allValues|]
let lines2 =
temp
|> Array.mapi (fun idx (t,b,op,ep,ip,i,av) ->
sprintf "%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s" title body ordinariePris extraPris inkopPris images allValues
)
let header = "title\tbody\tordinariePris\textraPris\tinkopPris\tallValues"
System.IO.File.WriteAllLines("test.csv",
Array.append [| header|]lines2, Encoding.UTF8)
thanks in advance
Upvotes: 0
Views: 49
Reputation: 2270
The problem with your code is that mapi
indexes over the elements of temp
, which means that you're only getting one column at a time. You want to retrieve one row at a time.
The following instead transposes your list of lists, so that indexing does what you want. It's also a little more generic-- you don't actually need to know the number of columns ahead of time. It does, however, assume that every column has the same number of elements in it.
let col1 = ["a"; "b"; "c"]
let col2 = ["1"; "2"; "3"]
let col3 = ["x"; "y"; "z"]
let cols = [col1; col2; col3]
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)
Note that this approach does not use an array of lists, since there was no obvious reason that you had to use an array. WriteAllLines
will happily accept any IEnumerable
.
If you do a lot of CSV writing, I recommend using a library like CsvHelper, since correctly handling when to quote or escape cell contents can be tricky.
Upvotes: 1