2017-01-05 4 views
4

Я следующие данные в формате JSON в виде documentdb, и я хотел бы разобрать это в F дерево # многоходовой предвзято объединениеDecode JSON Многосторонние дерева в F # Многосторонние Дерево дискриминированных Союза

"commentTree": { 
    "commentModel": { 
     "commentId": "", 
     "userId": "", 
     "message": "" 
     }, 
     "forest": [] 
    } 

F # многоходовой предвзято союз

type public CommentMultiTreeDatabaseModel = 
| CommentDatabaseModelNode of CommentDatabaseModel * list<CommentMultiTreeDatabaseModel> 

, где CommentMultiTreeDatabaseModel определяется как

type public CommentDatabaseModel = 
{ commentId : string 
    userId : string 
    message : string 
} 

Я подробно ссылаюсь на Fold/Recursion over Multiway Tree in f#. Я не уверен, где начать разбирать такую ​​структуру JSON в дерево многодорожечных F #. Любые предложения будут высоко оценены. Спасибо

+0

Я думаю, что реальный вопрос, который вы хотите задать, состоит в том, как проанализировать рекурсивную структуру json в соответствующий рекурсивный тип данных в F #? – scrwtp

ответ

3

Один из способов подумать об этом, посмотрев, какие данные вам нужны, чтобы построить CommentMultiTreeDatabaseModel. Он нуждается в CommentDatabaseModel и в списке CommentMultiTreeDatabaseModel. Таким образом, мы должны написать следующие две функции:

let parseComment (input : JSON) : CommentDatabaseModel = 
    ... 

let parseTree (input : JSON) : CommentMultiTreeDatabaseModel = 
    ... 

Но ждать, функция parseTree является тот, который мы пытаемся писать прямо сейчас! Поэтому вместо того, чтобы писать новую функцию, мы просто отмечаем нашу текущую функцию с помощью ключевого слова rec и вызываем ее там, где это необходимо.

Ниже приведен пример того, как это можно сделать. Ключевым моментом, который стоит посмотреть, является parseTree, который строит данные, рекурсивно называя себя. Я представил входные данные JSON с простым DU. Библиотека вроде Chiron может создать что-то вроде этого.

Обратите внимание, что этот код анализирует все JSON за один раз. Кроме того, это не хвостовая рекурсия, поэтому вам нужно быть осторожным с тем, насколько глубока ваша древовидная структура.

[<RequireQualifiedAccess>] 
type JSON = 
    | String of string 
    | Object of (string * JSON) list 
    | Array of JSON list 

type public CommentDatabaseModel = { 
    commentId : string 
    userId : string 
    message : string 
} 

type public CommentMultiTreeDatabaseModel = 
    | CommentDatabaseModelNode of CommentDatabaseModel * list<CommentMultiTreeDatabaseModel> 


let parseComment = function 
    | JSON.Object [ "commentId", JSON.String commentId; "userId", JSON.String userId; "message", JSON.String message ] -> 
     { 
      commentId = commentId 
      userId = userId 
      message = message 
     } 
    | _ -> failwith "Bad data" 

let rec parseTree (input : JSON) : CommentMultiTreeDatabaseModel = 
    match input with 
    | JSON.Object [ "commentModel", commentModel; "forest", JSON.Array forest ] -> 
     CommentDatabaseModelNode (parseComment commentModel, List.map parseTree forest) 
    | _ -> failwith "Bad data" 

let parse (input : JSON) : CommentMultiTreeDatabaseModel = 
    match input with 
    | JSON.Object [ "commentTree", commentTree ] -> 
     parseTree commentTree 
    | _ -> failwith "Bad data" 


let comment text =  
    JSON.Object [ 
     "commentId", JSON.String "" 
     "userId", JSON.String "" 
     "message", JSON.String text 
    ] 

let sampleData = 
    JSON.Object [ 
     "commentTree", JSON.Object [ 
      "commentModel", comment "one" 
      "forest", JSON.Array [ 
       JSON.Object [ 
        "commentModel", comment "two" 
        "forest", JSON.Array [] 
       ] 

       JSON.Object [ 
        "commentModel", comment "three" 
        "forest", JSON.Array [] 
       ] 
      ] 
     ] 
    ] 

parse sampleData 

(* 
val it : CommentMultiTreeDatabaseModel = 
    CommentDatabaseModelNode 
    ({commentId = ""; 
     userId = ""; 
     message = "one";}, 
    [CommentDatabaseModelNode ({commentId = ""; 
           userId = ""; 
           message = "two";},[]); 
     CommentDatabaseModelNode ({commentId = ""; 
           userId = ""; 
           message = "three";},[])]) 
*) 
+0

Благодарим за отзыв. Я временно отложил реализацию этой функции в своем приложении, но я вернусь к ней. Еще раз спасибо –

+1

Спасибо за ответ. Я только что реализовал его вместе с использованием Chiron –

 Смежные вопросы

  • Нет связанных вопросов^_^