複雑な簡易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)であったことを思い出すのは私です。
ご清聴ありがとうございました!

Source: https://habr.com/ru/post/J269461/


All Articles