2017-02-01 4 views
1

私はNewtonsoft.JsonNewtonsoft.Json.Fsharpライブラリを使用して、新しいJSONシリアライザを作成し、ファイルにストリームしました。私は大きなファイルを扱っているので、ファイルにストリームする機能が好きです。ストリーミングする前に、しばしばメモリの問題に遭遇しました。Microsoft.FSharpLuを使用してJSONをストリームにシリアライズ

私はシンプルなFXでストリーミング:

open Newtonsoft.Json 
open Newtonsoft.Json.FSharp 
open System.IO 

let writeToJson (path: string) (obj: 'a) : unit = 
    let serialized = JsonConvert.SerializeObject(obj) 
    let fileStream = new StreamWriter(path) 
    let serializer = new JsonSerializer() 

    serializer.Serialize(fileStream, obj) 

    fileStream.Close() 

これは素晴らしい作品。私の問題はJSON文字列は、私は必要としないものと絶対に雑然としていることです。

library(jsonlite) 
library(dplyr) 

q <- fromJSON("default.json") 

x <- 
    q %>% 
    flatten() 

x 

> x 
    FieldA FieldB.Case FieldB.Fields 
1  1  <NA>   NULL 
2  2  Some    3 
3  4  <NA>   NULL 
> sapply(x, class) 
     FieldA FieldB.Case FieldB.Fields 
    "numeric" "character"  "list" 

Iドン:これはJSONに書き込まれRに読み込まれている場合、例えば、

let m = 
    [ 
     (1.0M, None) 
     (2.0M, Some 3.0M) 
     (4.0M, None) 
    ] 

let makeType (tup: decimal * decimal option) = {FieldA = fst tup; FieldB = snd tup} 

let y = List.map makeType m 

Default.serialize y 

val it : string = 
    "[{"FieldA": 1.0}, 
    {"FieldA": 2.0, 
    "FieldB": { 
     "Case": "Some", 
     "Fields": [3.0] 
    }}, 
    {"FieldA": 4.0}]" 

は、ネストされたデータフレームとCaseエンドアップlistことに関連付けられたFieldsのいずれかが存在しますこれらのことをRで処理しなければならない。私はそれをすることができますが、それは迷惑で、たくさんの列を持つファイルがあれば、それは愚かです。

今朝、私はMicrosoft.FSharpLu.Json documentationで探し始めました。このライブラリにはCompact.serializeという関数があります。クイックテストは、このライブラリは、ネストされたデータフレームと任意のCaseField列に関連付けられているlistのための必要性を排除することを示唆しています。たとえば:

Compact.serialize y 

val it : string = 
    "[{ 
    "FieldA": 1.0 
    }, 
    { 
    "FieldA": 2.0, 
    "FieldB": 3.0 
    }, 
    { 
    "FieldA": 4.0 
    } 
    ]" 

この文字列がRに読み込まれ、

q <- fromJSON("compact.json") 

x <- q 
x 
> x 
    FieldA FieldB 
1  1  NA 
2  2  3 
3  4  NA 
> sapply(x, class) 
    FieldA FieldB 
"numeric" "numeric 

これはR.で処理するためにはるかに簡単であり、私はこのライブラリの使用を開始したいと思います。私はストリームにシリアライズするCompactシリアライザを得ることができる場合

しかし、私は知りません。私は.serializeToFile.desrializeStream、および.tryDeserializeStreamが、ストリームにシリアライズすることができます何を参照してください。 Compactがストリームへの書き込みを処理できるかどうかは誰にも分かりますか?どのように私はその仕事をすることができますか?

+1

「必要はありません」 –

+1

@FyodorSoikinうん、愚かなフレーズが、[ 'Microsoft.FSharpLu.Json'ライブラリ]に' Default.serialize'と 'Compact.serialize'からの出力の違いを見て(https://github.com/ Microsoft/fsharplu/wiki/fsharplu.json)。既定の 'JSON'文字列を' R 'に読み込むと、 'Option *'型の各フィールドに' 2 * n'フィールドがあります。 'コンパクト'シリアル化では、これらの追加フィールドは消えます。 – Steven

+1

これらのライブラリはインストールされておらず、テスト環境をセットアップするのに十分な時間がないため、「違いを見て」はできません。このように質問を表現することで、すでにこの正確な設定をしている人や余裕がある人に、潜在的な回答者を大幅に減らすことができます。 –

答えて

2

ヘルパーFSharpLu.JsonでCompactモジュールから欠落しているストリーミングするためにシリアル化するが、あなたは http://www.newtonsoft.com/json/help/html/SerializingJSON.htmからC#​​の例に従うことによってそれを行うことができるはずです。行に沿ったもの:

let writeToJson (path: string) (obj: 'a) : unit = 
    let serializer = new JsonSerializer() 
    serializer.Converters.Add(new Microsoft.FSharpLu.Json.CompactUnionJsonConverter()) 
    use sw = new StreamWriter(path) 
    use writer = new JsonTextWriter(sw) 
    serializer.Serialize(writer, obj) 
関連する問題