JSONオブジェクトで末尾のコンマを使用できますか?
質問
JSONオブジェクトまたは配列を手動で生成するとき、多くの場合、オブジェクトまたは配列の最後の項目に末尾のコンマを残す方が簡単です。たとえば、文字列の配列から出力するコードは次のようになります(擬似コードのようなC ++で):
s.append("[");
for (i = 0; i < 5; ++i) {
s.appendF("\"%d\",", i);
}
s.append("]");
次のような文字列を与える
[0,1,2,3,4,5,]
これは許可されていますか
解決
残念ながら JSON仕様では、末尾のコンマは許可されていません。それを許可するブラウザはいくつかありますが、通常はすべてのブラウザについて心配する必要があります。
一般に、問題を回避し、実際の値の前にコンマを追加しようとするため、次のようなコードになります。
s.append("[");
for (i = 0; i < 5; ++i) {
if (i) s.append(","); // add the comma only if this isn't the first entry
s.appendF("\"%d\"", i);
}
s.append("]");
forループ内の余分な1行のコードはほとんど高価ではありません...
何らかの形式の辞書からJSONに構造を出力するときに使用した別の代替方法は、各エントリの後に常にコンマを追加し(上記のように)、末尾にないダミーエントリを最後に追加することですカンマ(ただし、それは怠け者です;-&gt;)。
残念ながら配列ではうまく動作しません。
他のヒント
いいえ。 http://json.org で管理されているJSON仕様では、末尾のコンマは許可されていません。私が見たものから、一部のパーサーはJSON文字列を読み取るときに黙って許可する場合もあれば、エラーをスローする場合もあります。相互運用性のために、これを含めるべきではありません。
上記のコードは、配列ターミネータを追加するときに末尾のコンマを削除するか、アイテムの前にコンマを追加して最初のコンマをスキップするように再構築できます。
シンプルで安価で読みやすく、仕様に関係なく常に機能します。
$delimiter = '';
for .... {
print $delimiter.$whatever
$delimiter = ',';
}
$ delimへの冗長な割り当ては、非常に小さな代償です。 明示的なループはなく、個別のコードフラグメントがある場合にも同様に機能します。
既に述べたように、JSON仕様(ECMAScript 3に基づく)では、末尾のコンマが許可されていません。 ES&gt; = 5で許可されるため、純粋なJSでその表記を実際に使用できます。議論されており、一部のパーサーはそれをサポートしています( http:// bolinfest。 com / essays / json.html 、 http://whereswalden.com/2010/09/08/spidermonkey-json-change-trailing-commas-no-longer-accepted/ )が、仕様の事実です(< href = "http://json.org/" rel = "noreferrer"> http://json.org/ )JSONで動作しない 。そのことは...
... 0回目の反復で実際にループを分割し、末尾の1つではなく leading コンマを使用して比較コードの臭いを取り除くことができると誰も指摘していないのはなぜかと思いますループ内の実際のパフォーマンスオーバーヘッド。他のソリューションが提案するよりも実際に短く、単純で、高速なコードになります(ループ内に分岐/条件がないため)。
E.g。 (OPが提案するコードに似たCスタイルの擬似コード):
s.append("[");
// MAX == 5 here. if it's constant, you can inline it below and get rid of the comparison
if ( MAX > 0 ) {
s.appendF("\"%d\"", 0); // 0-th iteration
for( int i = 1; i < MAX; ++i ) {
s.appendF(",\"%d\"", i); // i-th iteration
}
}
s.append("]");
PHPコーダーは、 implode()をチェックすることをお勧めします。これは、文字列を使用して配列を結合します。
ドキュメント ...
から$array = array('lastname', 'email', 'phone');
echo implode(",", $array); // lastname,email,phone
興味深いことに、C&amp; C ++(および私はC#だと思いますが、私は確信していません)末尾のコンマを具体的に許可します-まさに与えられた理由のために:それはプログラムでリストをはるかに簡単に生成します。 JavaScriptが彼らのリードに従わなかった理由がわかりません。
JSON5を使用します。 JSONを使用しないでください。
- オブジェクトと配列には末尾にコンマを付けることができます
- オブジェクトキーは、有効な識別子である場合、引用符で囲まないことができます
- 文字列は単一引用符で囲むことができます
- 文字列は複数の行に分割できます
- 数字は16進数(基数16)にすることができます
- 数字は、先頭または末尾の小数点で開始または終了できます。
- 数字には、Infinityと-Infinityを含めることができます。
- 数字は明示的なプラス(+)記号で始めることができます。
- インライン(単一行)およびブロック(複数行)コメントの両方が許可されます。
- 余分な(コンマ)は、閉じ括弧の直前に表示される場合があります。
- 、(コンマ)省略がある場合、null値が挿入されます。
だから、私が理解しているように、書き込みを許可する必要があります:
[0,1,2,3,4,5,]
ただし、一部のパーサーは、予想される6ではなく、アイテム数として7を返すことがあります(ダニエル・アーウィッカーが指摘したIE8など)。
編集済み:
JSON文字列を
ただし、RFC 4627仕様には次のように記載されています。
2.3。配列
配列構造は、ゼロを囲む角括弧として表されます 以上の値(または要素)。要素はコンマで区切られます。
array = begin-array [ value *( value-separator value ) ] end-array
これもまた、解釈の問題です。 要素はコンマで区切られていると書くと(最後の要素のように特別な場合については何も述べずに)、両方の方法で理解できます。
PS RFC 4627は(明示的に述べられている)標準ではなく、RFC 7159(提案されている標準)によって既に廃止されています RFC 7159
過去の経験から、ブラウザによってJSONの末尾のコンマが異なる方法で処理されることがわかりました。
FirefoxとChromeの両方で問題なく処理できます。しかし、IE(すべてのバージョン)は壊れているようです。つまり、スクリプトの残りの部分を読むのをやめて中断するということです。
このことを念頭に置き、準拠コードを書くのが常に良いという事実を念頭に置いて、末尾のコンマがないことを確認するための余分な努力を費やすことをお勧めします。
:)
現在のカウントを保持し、合計カウントと比較します。現在のカウントが合計カウントより少ない場合、コンマを表示します。
JSON生成を実行する前に合計カウントがない場合、機能しない場合があります。
次に、PHP 5.2.0以降を使用している場合は、組み込みのJSON APIを使用して応答をフォーマットできます。
Relaxed JSONを使用すると、末尾にコンマを付けることができます。コンマを省くか。オプションです。
JSONに似たドキュメントを解析するためにすべてのコンマが存在する必要がある理由はありません。
Relaxed JSON仕様を見ると、元のJSON仕様がどれほど「ノイズが多い」かがわかります。コンマと引用符が多すぎます...
このオンラインRJSONパーサーを使用して例を試してみて、正しく解析されることを確認することもできます。
http://www.relaxedjson.org/docs/converter.html?source=%5B0%2C1%2C2%2C3%2C4%2C5%2C%5D
通常、配列をループし、文字列のすべてのエントリの後にカンマを付けます。ループの後、最後のコンマをもう一度削除します。
最善の方法ではないかもしれませんが、ループの最後のオブジェクトであるかどうかを毎回確認するよりも安価です。
推奨されていませんが、このようにして解析することはできます。
jsonStr = '[0,1,2,3,4,5,]';
let data;
eval('data = ' + jsonStr);
console.log(data)
ループ内のif-branchを回避する方法があります。
s.append("[ "); // there is a space after the left bracket
for (i = 0; i < 5; ++i) {
s.appendF("\"%d\",", i); // always add comma
}
s.back() = ']'; // modify last comma (or the space) to right bracket
forループは配列または類似の反復可能なデータ構造を反復処理するために使用されるため、図のように配列の長さを使用できます
awk -v header="FirstName,LastName,DOB" '
BEGIN {
FS = ",";
print("[");
columns = split(header, column_names, ",");
}
{ print(" {");
for (i = 1; i < columns; i++) {
printf(" \"%s\":\"%s\",\n", column_names[i], $(i));
}
printf(" \"%s\":\"%s\"\n", column_names[i], $(i));
print(" }");
}
END { print("]"); } ' datafile.txt
datafile.txtを含む
Angela,Baker,2010-05-23
Betty,Crockett,1990-12-07
David,Done,2003-10-31