我不想使用此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"
答案 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)