web-dev-qa-db-ja.com

JSONオブジェクトで末尾のコンマを使用できますか?

JSONオブジェクトまたは配列を手動で生成するとき、多くの場合、オブジェクトまたは配列の最後の項目に末尾のコンマを残す方が簡単です。たとえば、文字列の配列から出力するコードは次のようになります(C++のような擬似コード)

s.append("[");
for (i = 0; i < 5; ++i) {
    s.appendF("\"%d\",", i);
}
s.append("]");

のような文字列を与えます

[0,1,2,3,4,5,]

これは許可されていますか?

353
Ben Combee

残念ながら 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に構造を出力するときに使用した別の代替方法は、(上記のように)各エントリの後に常にコンマを追加し、最後にコンマのないダミーエントリを追加することです(ただし、それはただ怠け者です;->)。

残念ながら、配列ではうまく機能しません。

216
brianb

いいえ。 http://json.org で管理されているJSON仕様では、末尾のコンマは許可されていません。私が見たものから、一部のパーサーはJSON文字列を読み取るときに黙って許可する場合もあれば、エラーをスローする場合もあります。相互運用性のために、これを含めるべきではありません。

上記のコードは、配列ターミネーターを追加するときに末尾のコンマを削除するか、アイテムの前にコンマを追加して最初のコンマをスキップするように再構成できます。

124
Ben Combee

シンプルで安価で読みやすく、仕様に関係なく常に機能します。

$delimiter = '';
for ....  {
    print $delimiter.$whatever
    $delimiter = ',';
}

$ delimへの冗長な割り当ては、非常に小さな代償です。明示的なループではなく、個別のコードフラグメントがある場合にも同様に機能します。

98
Overflowee

JavaScriptでは末尾のコンマを使用できますが、IEでは機能しません。 Douglas CrockfordのバージョンレスJSON仕様では許可されていませんでした。バージョンレスであったため、これは変更されるべきではありませんでした。 ES5 JSON仕様では拡張機能として許可されていましたが、Crockfordの RFC 4627 は許可されていなかったため、ES5はそれらを許可しませんでした。 Firefox 追随。 Internet Explorerは、私たちが素晴らしいものを手に入れることができない理由です。

19
Tobu

既に述べたように、JSON仕様(ECMAScript 3に基づく)では、末尾のコンマが許可されていません。 ES> = 5で許可されるため、純粋なJSでその表記を実際に使用できます。議論されており、一部のパーサーdidはそれをサポートしています( http://bolinfest.com/essays/json.htmlhttp://whereswalden.com/2010/09/08/spidermonkey-json-change-trailing-commas-no-longer-accepted/ )、しかし、それは( http://json.org/ に示されているように)仕様の事実であり、すべきではないJSONで動作します。そのことは言った...

... 0回目の繰り返しで実際にループを分割し、1つ後の代わりにleadingカンマを使用できることを誰も指摘していないのはなぜだろう比較コードの臭いとループ内の実際のパフォーマンスオーバーヘッドを取り除き、提案された他のソリューションよりも実際に短く、シンプルで高速なコードが得られます(ループ内に分岐/条件がないため)。

例えば。 (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("]");
13
vaxquis

PHPコーダーは、チェックアウトしたいかもしれませんimplode()。これは、文字列を使用して配列を結合します。

docs ...から.

$array = array('lastname', 'email', 'phone');
echo implode(",", $array); // lastname,email,phone
12
Rik Heywood

興味深いことに、CとC++(およびC#とは思いますが、確信はありませんが)末尾のコンマを具体的に許可します-まさに与えられた理由から:プログラムでリストをはるかに簡単に生成できます。 JavaScriptが彼らのリードに従わなかった理由がわかりません。

7
James Curran

JSON5を使用します。 JSONを使用しないでください。

  • オブジェクトと配列には末尾にコンマを付けることができます
  • オブジェクトキーは、有効な識別子である場合、引用符で囲まないことができます
  • 文字列は一重引用符で囲むことができます
  • 文字列は複数の行に分割できます
  • 数値は16進数(16進数)にすることができます
  • 数値は、(先頭または末尾の)小数点で開始または終了できます。
  • 数字には、Infinityおよび-Infinityを含めることができます。
  • 数字は、明示的なプラス(+)記号で始めることができます。
  • インライン(単一行)およびブロック(複数行)コメントの両方が許可されます。

http://json5.org/

https://github.com/aseemk/json5

4
user619271

Class JSONArray specification によると:

  • 追加の、(コンマ)が閉じ括弧の直前に表示される場合があります。
  • 、(コンマ)省略がある場合、null値が挿入されます。

それで、私が理解しているように、それは書くことを許されるべきです:

[0,1,2,3,4,5,]

ただし、一部のパーサーは、予想される6ではなく、アイテム数として7を返すことがあります(ダニエル・アーウィッカーが指摘したIE8など)。


編集済み:

私はこれを見つけました JSON Validator JSON文字列を RFC 4627 (JavaScript Object Notationのapplication/jsonメディアタイプ)およびJavaScript言語仕様に対して検証します。実際、ここでは、末尾にコンマが付いている配列は、RFC 4627仕様ではなくJavaScriptに対してのみ有効であると見なされます。

ただし、RFC 4627仕様には次のことが記載されています。

2.3。配列

配列構造は、0個以上の値(または要素)を囲む角括弧として表されます。要素はコンマで区切られます。

array = begin-array [ value *( value-separator value ) ] end-array

私にとって、これは再び解釈の問題です。 と書くと、要素はコンマで区切られます(最後の要素のように特別な場合については何も述べずに)、両方の方法で理解できます。

追伸RFC 4627は(明示的に述べられているように)標準ではなく、RFC 7159(提案されている標準)によってすでに廃止されています RFC 7159

2
Timoty Weis

現在のカウントを保持し、合計カウントと比較します。現在のカウントが合計カウントより少ない場合、コンマを表示します。

JSON生成を実行する前に合計数がない場合、機能しない可能性があります。

繰り返しますが、PHP 5.2.0以降を使用している場合は、組み込みのJSON APIを使用して応答をフォーマットするだけです。

1
eddie

過去の経験から、JSONの末尾のコンマはブラウザーごとに異なる方法で処理されることがわかりました。

FirefoxとChromeの両方が問題なく処理します。しかし、IE(すべてのバージョン)は壊れているようです。つまり、スクリプトの残りの部分を読むのをやめて中断するということです。

それを念頭に置き、準拠コードを書くのは常に素晴らしいことを念頭に置いて、末尾のコンマがないことを確認するために余分な努力を払うことをお勧めします。

:)

1
dnshio

Relaxed JSONを使用すると、末尾のカンマを使用したり、カンマを省略したりできます。オプションです。

JSONに似たドキュメントを解析するためにコンマが必要になる理由はまったくありません。

Relaxed JSON仕様を見てください。元のJSON仕様がどれだけ「うるさい」かがわかります。あまりにも多くのコンマと引用符...

http://www.relaxedjson.org

このオンラインRJSONパーサーを使用して例を試してみて、正しく解析されるのを確認することもできます。

http://www.relaxedjson.org/docs/converter.html?source=%5B0%2C1%2C2%2C3%2C4%2C5%2C%5D

1
Steven Spungin

推奨されませんが、それでも解析するためにこのようなことをすることができます。

jsonStr = '[0,1,2,3,4,5,]';
let data;
eval('data = ' + jsonStr);
console.log(data)
0
feibing

ループ内の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
0
Zhang Boyang

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
0

通常、配列をループし、文字列のすべてのエントリの後にカンマを付けます。ループの後、最後のコンマを再び削除します。

最善の方法ではないかもしれませんが、ループの最後のオブジェクトであるかどうかを毎回確認するよりも安価です。

0
Nils