F# 将集合/序列投影到单个记录中

F# 将集合/序列投影到单个记录中,f#,F#,我正在解析HTML(通过HAP),现在正在解析每行的特定表列内容(TD元素的集合) 注意:不使用FSharp.Data的HTML解析器,因为它被包含导致CSS选择器失败的代码的HTML破坏(已知问题) 我试图将一行数据映射到的类型(10个不同类型的“列”): 我的丑陋但工作正常的函数将列位置映射到记录字段(是的,任何未正确解析的内容都会爆炸): 一些测试代码: let chartRow = { C0 = ""; C1 = ""; C2 = 0; C3 = 0.0M; C4 = "" ; C5 =

我正在解析HTML(通过HAP),现在正在解析每行的特定表列内容(TD元素的集合)

注意:不使用FSharp.Data的HTML解析器,因为它被包含导致CSS选择器失败的
代码的HTML破坏(已知问题)

我试图将一行数据映射到的类型(10个不同类型的“列”):

我的丑陋但工作正常的函数将列位置映射到记录字段(是的,任何未正确解析的内容都会爆炸):

一些测试代码:

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))
问题是,由于我传入一条不可变记录,并通过
Seq.mapi
(使用索引映射到列号)从dailyRow函数接收一条新记录,因此我将得到10条记录,每条记录都设置了一个属性值


在C#中,我只需传递一个ref'd对象并将其更新到位,F#惯用的处理方法是什么

最简单的选项,如果您不介意数组分配:

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] }

难道你不能把它折叠起来,然后累加一个结果对象吗?就像你在C#中做的那样,这样你的代码就会简单得多,而且是惯用的。“record with”构造一次可以接受多个字段,但在这种情况下,最好在函数中实例化该记录,因为毕竟您将分配所有字段。谢谢
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))
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] }