在F#中迭代JArray而无需for循环

时间:2018-07-10 12:46:58

标签: f#

我不想使用此for循环来迭代JArray。还有其他方法可以代替for循环吗?

let tablesInJson = jsonModel.["tables"] :?> JArray  //Converting JOject into JArray

    for table in tablesInJson do 

    let TableName = table.["name"] :?> JValue
    let columns = table.["columns"] :?> JArray

    for col in columns do

        let name = col.["name"] :?> JValue
        let types = col.["type"] :?> JValue
        let length = col.["length"] :?> JValue

        let Result_ = sqlTableInfos 
                    |> List.tryFind (fun s -> s.TableName = TableName.ToString() && s.ColumnName = name.ToString()) 

        if Result_ = Unchecked.defaultof<_> then
            printfn "is null"
        else
            printfn "not null"

2 个答案:

答案 0 :(得分:3)

如果您想遍历一个集合并执行命令式操作,则在F#中,使用循环for是惯用的方式,您应该使用它。毕竟,for是一种F#语言构造!它之所以存在是有原因的,原因是它使您可以轻松地编写遍历集合并为每个元素执行操作的代码!

在某些情况下,for循环不太适合。例如,如果您想将列的集合转换为包含有关表信息的新集合。然后,您可以使用Seq.map

let tableInfos = columns |> Seq.map (fun col ->
    let name = col.["name"] :?> JValue
    let types = col.["type"] :?> JValue
    let length = col.["length"] :?> JValue
    let result = sqlTableInfos |> List.tryFind (fun s -> 
      s.TableName = TableName.ToString() && s.ColumnName = name.ToString()) 
    if result = Unchecked.defaultof<_> then None
    else Some result)

这看起来像是您可能要尝试做的事情-但很难说。您的问题并未说明您实际上要解决的问题是什么。

您使用printfn的示例可能会误导您,因为如果您实际上只是想打印,那么for循环是实现此目的的最佳方法。

答案 1 :(得分:0)

您可以使用Seq模块在​​JArray上执行序列处理操作。在您的情况下,我想我可能会针对第二个for循环(在列上)而不是外部循环执行此操作。原因是,如果将内部循环中的代码分解为函数,则可以使用流水线和部分应用程序来清理代码:

open Newtonsoft.Json
open Newtonsoft.Json.Linq

type SqlTableInfo = {TableName: string; ColumnName: string}

let tablesInJson = JArray()
let sqlTableInfo = []

let tryFindColumn (tableName: JValue) (column: JToken) =
    let columnName = column.["name"] |> unbox<JValue>

    if sqlTableInfo |> List.exists (fun s -> s.TableName = tableName.ToString() && s.ColumnName = columnName.ToString())
    then printfn "Table %A, Column %A Found" tableName columnName 
    else printfn "Table %A, Column %A Found" tableName columnName 

for table in tablesInJson do 
    let tableName = table.["name"] |> unbox<JValue>
    table.["columns"] 
    |> unbox<JArray> 
    |> Seq.iter (tryFindColumn tableName)