F # - запись списка кортежей в файл CSV - PullRequest
0 голосов
/ 14 декабря 2018

Мне нужно написать список кортежей в CSV-файл.Кортежи могут иметь переменное количество полей и типов!Мои текущие усилия следующие:

module SOQN = 

    open System
    open System.IO
    open FSharp.Data

    let lstTuples = [(2, false, 83.23, "Alpha", 29); (3, true, 79.11, "Beta", 47); (5, false, 61.13, "Gamma", 71)]

    let main() =
        do 
            use writer = new StreamWriter(@"C:\tmp\ListTuples.csv")
            let lstTuplesIter = lstTuples |> List.iter writer.WriteLine
            lstTuplesIter
        0

    [<EntryPoint>]
    main() |> ignore

// Actual Output: 
// (2, False, 83.23, Alpha, 29)
// (3, True, 79.11, Beta, 47)
// (5, False, 61.13, Gamma, 71)
// 
// Expected Output: 
// 2, False, 83.23, Alpha, 29
// 3, True, 79.11, Beta, 47
// 5, False, 61.13, Gamma, 71
//

Чего мне не хватает?

Ответы [ 3 ]

0 голосов
/ 14 декабря 2018

Хотя я согласен с @Jackson, что это, вероятно, неправильная структура данных, для произвольной длины вам, вероятно, понадобится отражение.

Вы видите, как они обращаются к компонентам кортежа ("ItemN", где N - число) здесь .

Вы можете перебирать свойства и получать значения дляваш динамический случай.

Имейте в виду, что использование отражения довольно неэффективно (см. здесь )

0 голосов
/ 14 декабря 2018

Спасибо вам обоим за пользу вашего опыта.Следующий фрагмент работает, как требуется (адаптируя код Томаса Петричека):

module SOANS = 

open System
open System.IO
open FSharp.Reflection
open FSharp.Data

let lstTuples = [(2, false, 83.23, "Alpha", 29); (3, true, 79.11, "Beta", 47); (5, false, 61.13, "Gamma", 71)]

// https://stackoverflow.com/questions/13071986/write-a-sequence-of-tuples-to-a-csv-file-f    
let tupleToString t = 
  if FSharpType.IsTuple(t.GetType()) then
    FSharpValue.GetTupleFields(t)
    |> Array.map string
    |> String.concat ", "
  else failwith "not a tuple!"

let allIsStrings t = 
  t 
  |> Seq.map tupleToString
  |> Array.ofSeq

let main() =
    let lstTuples = [(2, false, 83.23, "Alpha", 29); (3, true, 79.11, "Beta", 47); (5, false, 61.13, "Gamma", 71)]
    let outTest = allIsStrings(lstTuples)
    File.WriteAllLines(@"C:\tmp\ListTuples.csv", outTest)
    0

[<EntryPoint>]
main() |> ignore
0 голосов
/ 14 декабря 2018

Что вы делаете, так это записываете интерпретацию кортежа на F #, которая включает в себя окружающие скобки. Если вы деконструируете кортеж и используете sprintf для форматирования вывода, вы можете получить желаемый результат:

lstTuples |> List.iter (fun (a,b,c,d,e) -> writer.WriteLine (sprintf "%d,%A,%.2f,%s,%d" a b c d e ))
...