Проецирование коллекции / последовательности в одну запись - PullRequest
0 голосов
/ 27 февраля 2019

Я анализирую HTML (через HAP) и теперь анализирую содержимое конкретной колонки таблицы для каждой строки (коллекция элементов TD)

Примечание. Не используется синтаксический анализатор HTML FSharp.Data, поскольку он не работает с HTMLкоторый содержит <Script> код, который вызывает сбой селекторов CSS (известная проблема)

Тип, который я пытаюсь отобразить в строку данных (10 "столбцов" разных типов):

type DailyRow = { C0: string; C1: string; C2: int; C3: decimal; C4: string; C5: string; C6: int; C7: decimal; C8: decimal; C9: int }

Моя уродливая, но работающая функция, которая отображает положения столбцов в поле записи (да, все, что не анализируется правильно, должно взорваться):

let dailyRow = fun (record:DailyRow, column:int, node:HtmlNode) ->
        printfn "dailyRow: Column %i has value %s" column node.InnerText
        match column with 
        | 0 -> {record with C0 = node.InnerText }
        | 1 -> {record with C1 = node.InnerText }
        | 2 -> {record with C2 = (node.InnerText |> int) }
        | 3 -> {record with C3 = Decimal.Parse(node.InnerText, NumberStyles.Currency) }
        | 4 -> {record with C4 = node.InnerText }
        | 5 -> {record with C5 = node.InnerText }
        | 6 -> {record with C6 = Int32.Parse(node.InnerText, NumberStyles.AllowThousands) }
        | 7 -> {record with C7 = Decimal.Parse(node.InnerText, NumberStyles.Currency) }
        | 8 -> {record with C8 = Decimal.Parse(node.InnerText, NumberStyles.Currency) }
        | 9 -> {record with C9 = (node.InnerText |> int) }
        | _ -> raise (System.MissingFieldException("New Field in Chart Data Found: " + column.ToString()))

Некоторые тестовые коды:

let chartRow = { C0 = ""; C1 = ""; C2 = 0; C3 = 0.0M; C4 = "" ; C5 = ""; C6 = 0; C7 = 0.0M; C8 = 0.0M; C9 = 0 }
let columnsToParse = row.SelectNodes "td" // 1 row of 10 columns
let x = columnsToParse
                |> Seq.mapi (fun i x -> dailyRow(chartRow, i, x))

Проблема, поскольку я передаю неизменяемую запись и получаю новую запись из функции dailyRow через Seq.mapi (используя индекс для сопоставления с номером столбца), в итоге получится 10 записей, каждая с однойих значения свойства установлены.

В C # я бы просто передал dailyRow объект ref'd и обновил бы его на месте, каков будет F # идиоматический способ обработки этого?

1 Ответ

0 голосов
/ 27 февраля 2019

Самый простой вариант, если вы не возражаете против выделения массива:

let nodes = seq [...]
let arr = nodes |> Seq.map (fun n -> n.InnerText) |> Array.ofSeq
let record = 
    { C0 = arr.[0]
      C1 = arr.[1]
      C2 = int arr.[2]
      C3 = Decimal.Parse(arr.[3], NumberStyles.Currency)
      C4 = arr.[4]
      C5 = arr.[5]
      C6 = Int32.Parse(arr.[6], NumberStyles.AllowThousands)
      C7 = Decimal.Parse(arr.[7], NumberStyles.Currency)
      C8 = Decimal.Parse(arr.[8], NumberStyles.Currency)
      C9 = int arr.[9] }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...