複雑な簡易JSON

このような有名で非常にシンプルなテキスト形式のJSONがあります



JSON形式では、 nullbooleantruefalse )、 numberstringarrayobjectのタイプが定義されています



しかし、JSONデータをnumberstringarrayobjectの 4つのタイプだけで表すタスクを設定するとどうなるでしょうか?







異常なプログラミングへようこそ!

プログラムゲスト: NSNJSON (Not So Normal JSON)!





内容



用語と表記

「単純な」タイプのビュー

コンテナタイプのビュー

JSONリカバリー

「単純な」タイプのJSONリカバリー

コンテナタイプのJSONリカバリ



ドライバー

おわりに



このタスクに少し正式にアプローチしてみましょう。 この記事では、 json.orgから取得した表記を使用します。 また、便宜上、少し追加します。



用語と表記



タイプboolean = trueを導入します |



また、値が文字列型の値のサブセットである型名、オブジェクトフィールドの正しい名前である値を紹介します。



NSNJSONビューは3つのフィールドのみを使用します。





「単純な」タイプのビュー



「単純な」タイプには、 nullbooleanstringnumberが含まれます。



P nullの NSNJSON表現を定義します :null- > オブジェクト

value -> { "t": "null" }
      
      





NSNJSON表現の定義P true :true- > オブジェクト

 value -> { "t": "boolean", "v": 1 }
      
      





NSNJSON表現の定義P false :false- > オブジェクト

 value -> { "t": "boolean", "v": 0 }
      
      





PのNSNJSON表現を定義stringstringobject

 value -> { "t": "string", "v": value }
      
      





P 番号の NSNJSON表現を定義する: 数値オブジェクト

 value -> { "t": "number", "v": value }
      
      





P simpleの NSNJSON表現を定義します「単純な」タイプ-> オブジェクト

P simple (value)= P null (value)、 valuenull値の場合、

P simple (value)= P true (value)、 valueが true型の値の場合

P simple (value)= P false (value)、 valuefalse値の場合、

P simple (value)= P string (value)、 valueが string型の値の場合、

P simple (value)= P number (value)valueがタイプnumberの値の場合。



コンテナタイプのビュー



以下を「コンテナ」タイプに帰属させます: arrayobject



配列オブジェクトの両方に要素が含まれているため、次のことが必要です。



最初に、「コンテナ」、つまり「シンプル」タイプのみの値を検討します。



まず、配列、つまりarray型の値を扱いましょう。



データ配列をarray型の値とすると、次のように配列を表すことができます。

データ=(e 1 、...、e n )、

ここで、すべてのi = 1、...、n、

nは配列の長さ、

e i-配列の要素-「単純な」型の値。



プレゼンテーション関数P simpleデータ配列の各要素に適用します。



dataElementsPresentation =(P simple (e 1 )、...、P simple (e n ))。



P 配列の NSNJSON表現を定義します配列オブジェクト

 data -> { "t": "array", "v": dataElementsPresentation }
      
      





それでは、オブジェクト、つまりobject型の値を扱いましょう。



データオブジェクトをobject型の値とすると、次のようにオブジェクトを表すことができます。

data = {(name 1 、value 1 )、...、(name n 、value n )}、

ここで、すべてのi = 1、...、n、

nはオブジェクトのフィールド数です。

(名前i 、値i )-オブジェクトのフィールド、

名前i-フィールド名

i-フィールド値-「単純」タイプの値。



JSON仕様では、オブジェクトは順序付けられていないフィールドのセットであると規定されていますが、いずれの場合も、オブジェクトのすべてのフィールドを常に反復処理し、ソート順に番号を付けることができます。 この手法を使用すると、一般性を失うことなく、 データオブジェクトをフィールドの配列として表すことができます。



valuePresentationを、プレゼンテーション関数P simpleをvalueのに適用した結果とします



P フィールドの NSNJSON表現を定義します名前 × オブジェクト

 (name, value) -> { "n": name, "t": valuePresentation.t, "v": valuePresentation.v }
      
      





P フィールド表現関数をデータオブジェクトの各フィールドに適用します。



dataFieldsPresentation =(P フィールド (名前1 、値1 )、...、P フィールド (名前n 、値n ))。



P オブジェクトの NSNJSON表現を定義する: オブジェクトオブジェクト

 data -> { "t": "object", "v": dataElementsPresentation }
      
      





P コンテナーの NSNJSON表現を定義します「コンテナー」タイプ-> オブジェクト

P コンテナ (値)= P 配列 (値)、 値が 配列型の値の場合、

P コンテナ (値)= P オブジェクト (値)(値がオブジェクト型の値の場合)



最後に、P jsonの最終的なNSNJSON表現を定義します。json- > object

P json (値)= P simple (値)、 valueが 「単純」型の値である場合、

値が 「コンテナ」タイプの値である場合、P json (値)= P container (値)。



現在、「コンテナ」タイプのプレゼンテーションアルゴリズムで、P 単純関数の代わりにP json関数が使用されている場合、任意のJSON値を含む「コンテナ」で動作できるプレゼンテーション関数を取得します。



したがって、有効なJSONデータを表すためのスキームは、 numberstringarrayobjectの 4つのJSONタイプのみを使用して構築されました。



JSONリカバリー



JSONがあり、それからNSNSJONを取得できます。

しかし、元のJSONを復元できるようになりましたか?

できます。



値P typeの JSON型を取得するための関数を定義します: オブジェクト文字列

 presentation -> presentation.t
      
      





typeを P type関数をプレゼンテーションに適用した結果とします。



「単純な」タイプのJSONリカバリー



回復関数を定義するR nullオブジェクトnull

 presentation -> if (type == "null") { return null; }
      
      





回復関数R 番号を定義しますオブジェクト文字列

 presentation -> if (type == "string") { return presentation.v; }
      
      





回復関数R 番号を定義: オブジェクト番号

 presentation -> if (type == "number") { return presentation.v; }
      
      





回復関数を定義するR booleanobjectboolean

 presentation -> if (type == "boolean") { return presentation.v != 0; }
      
      





回復関数を定義するR simpleオブジェクト「単純」タイプ

R simple (presentation)= R null (presentation)、 type = "null"の場合、

R simple (presentation)= R string (presentation)、 type =“ string”の場合、

type = "number"の場合、R simple (presentation)= R number (presentation)。

R simple (presentation)= R boolean (presentation)、 type = "boolean"の場合、



コンテナタイプのJSONリカバリ



前と同様に、最初に「コンテナ」、つまり「単純な」タイプのみの値を検討します。



データ配列のプレゼンテーションがあります



presentation.v配列の各要素に回復関数R simpleを適用します。

データ=(e 1 、...、e n )、

ここで、すべてのi = 1、...、n、

e i -R simple (presentation.v [i])-配列の要素。



回復関数R 配列を定義: オブジェクト配列

 presentation -> if (type == "array") { return data; }
      
      





データオブジェクトのプレゼンテーションがあります。



presentation.v配列の各要素に単純な回復関数Rを適用し、フィールドnの値を使用してオブジェクトのフィールド復元します。

データ=(e 1 、...、e n )、

ここで、すべてのi = 1、...、n、

e i- (名前i 、値i )-オブジェクトのフィールド、

name i -presentation.v [i] .n-フィールド名

i -R simple (presentation.v [i])-フィールド値。



回復関数R オブジェクトを定義する: オブジェクトオブジェクト

 presentation -> if (type == "object") { return data; }
      
      





回復機能R コンテナを定義しますオブジェクト「コンテナ」タイプ

R コンテナ (プレゼンテーション)= R 配列 (値)、 type = "array"の場合、

type = "object"の場合、R コンテナ (プレゼンテーション)= R オブジェクト (値)。



そして最後に、回復関数R jsonを定義します: オブジェクトjson

R json (プレゼンテーション)= R simple (プレゼンテーション)、「シンプル」タイプの値が復元された場合、

「コンテナ」タイプの値が復元される場合、R json (プレゼンテーション)= R コンテナ (プレゼンテーション)。



現在、R 単純関数ではなく「コンテナ」タイプの回復アルゴリズムでR json関数を使用すると、JSON値を含む「コンテナ」で動作できるプレゼンテーション関数が得られます。





結論として、NSNJSON形式の使用を示す簡単な例をいくつか示します。



ジョンソン NSNJSON(それほど正常ではないJSON)
 null
      
      



 { "t": "null" }
      
      



 true
      
      



 { "t": "boolean", "v": 1 }
      
      



 false
      
      



 { "t": "boolean", "v": 0 }
      
      



 213
      
      



 { "t": "number", "v": 213 }
      
      



 "Habrahabr"
      
      



 { "t": "string", "v": "Habrahabr" }
      
      



 [ null, true, false, 213, "Habrahabr" ]
      
      



 { "t": "array", "v": [ { "t": "null" }, { "t": "boolean", "v": 1 }, { "t": "boolean", "v": 0 }, { "t": "string", "v": "Habrahabr" } ] }
      
      



 [ { "userId": 17, "status": "online" }, { "userId": 19, "status": "offline" } ]
      
      



 { "t": "array", "v": [ { "t": "object", "v": [ { "n": "userId", "t": "number", "v": 17 }, { "n": "status", "t": "string", "v": "online" } ] }, { "t": "object", "v": [ { "n": "userId", "t": "number", "v": 19 }, { "n": "status", "t": "string", "v": "offline" } ] } ] }
      
      



 { "null_field": null, "true_field": true, "false_field": false, "number_field": 213, "string_field": "Habrahabr", "array_field": [ "JSON", "NSNJSON" ] }
      
      



 { "t": "object", "v": [ { "n": "null_field", "t": "null" }, { "n": "true_field", "t": "boolean", "v": 1 }, { "n": "false_field", "t": "boolean", "v": 0 }, { "n": "number_field", "t": "number", "v": 213 }, { "n": "string_field", "t": "string", "v": "Habrahabr" }, { "n": "array_field", "t": "array", "v": [ { "t": "string", "v": "JSON" }, { "t": "string", "v": "NSNJSON" } ] } ] }
      
      









ドライバー



この形式で遊んでみたい人のために、2つの小さなドライバーを作成しました。



ドライバーはGitHubのプロジェクトページで入手できます: nsnjson

ドライバー:



npmjs.comの愛好家に朗報です!

Node.jsドライバーも利用可能になりました



また、Javaドライバーを使用してNSNJSONを試してみたい場合は、プロジェクトページで、ドライバーを手動でダウンロードしないようにMaven pom.xml ファイルを構成する方法に関する指示を見つけることができます。 :)



おわりに



今日、プログラム「Abnormal Programming」のゲストがNSNJSON(Not So Normal JSON)であったことを思い出すのは私です。

ご清聴ありがとうございました!



All Articles