このような有名で非常にシンプルなテキスト形式の
JSONがあります 。
JSON形式では、 
null 、 
boolean ( 
true 、 
false )、 
number 、 
string 、 
array 、 
objectのタイプが定義されてい
ます 。
しかし、JSONデータを
number 、 
string 、 
array 、 
objectの 4つのタイプだけで表すタスクを設定するとどうなるでしょうか?

異常なプログラミングへようこそ!
プログラムゲスト: 
NSNJSON (Not So Normal JSON)!
内容
用語と表記「単純な」タイプのビューコンテナタイプのビューJSONリカバリー「単純な」タイプのJSONリカバリーコンテナタイプのJSONリカバリ例ドライバーおわりにこのタスクに少し正式にアプローチしてみましょう。 この記事では、 
json.orgから
取得した表記を使用します。 また、便宜上、少し追加します。
用語と表記
タイプ
boolean = 
trueを導入し
ます | 
偽また、値が
文字列型の値のサブセットである型名、オブジェクトフィールドの正しい名前である値を紹介します。
NSNJSONビューは3つのフィールドのみを使用します。
- t- タイプ -値タイプ(必須フィールド)、
 - v- 値 -値(必須フィールド)、
 - n- 名前 -フィールド名(オブジェクトフィールド表現で使用)。
 
「単純な」タイプのビュー
「単純な」タイプには、 
null 、 
boolean 、 
string 、 
numberが含まれます。
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表現を定義
string : 
string → 
object value -> { "t": "string", "v": value } 
P 
番号の NSNJSON表現を定義する: 
数値 → 
オブジェクト value -> { "t": "number", "v": value } 
P 
simpleの NSNJSON表現を定義し
ます 。 
「単純な」タイプ-> オブジェクト :
P 
simple (value)= P 
null (value)、 
valueが
null値の場合、
P 
simple (value)= P 
true (value)、 
valueが true型の値の
場合 、
P 
simple (value)= P 
false (value)、 
valueが
false値の場合、
P 
simple (value)= P 
string (value)、 
valueが string型の値の場合、
P 
simple (value)= P 
number (value)valueがタイプ
numberの値の場合。
コンテナタイプのビュー
以下を「コンテナ」タイプに帰属させます: 
array 、 
object 。
配列と
オブジェクトの両方に要素が含まれているため、次のことが必要です。
- まず、各要素の表現を定義し、
 - 第二に、その要素の表現に基づいて、「コンテナ」全体の最終的なプレゼンテーションを決定します。
 
最初に、「コンテナ」、つまり「シンプル」タイプのみの値を検討します。
まず、配列、つまり
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データを表すためのスキームは、 
number 、 
string 、 
array 、 
objectの 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 
boolean : 
object → 
boolean 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)であったことを思い出すのは私です。
ご清聴ありがとうございました!