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


392

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

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

のような文字列を与える

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

これは許可されますか?


66
数日前にWebで検索する必要がありました。私はここでSOに答えを見つけられなかったので、サイトの使命をたどるときに質問を投げかけ、他の人が見つけられるように答えました。これはジェフがここでしたかったとはっきり言ったものです。
Ben Combee、2008年

5
ジェフが言ったように、SOを、検索に時間を費やさなければならなかったものの「ノートブック」として使用することは完全に良いと思います。確かに、これはそれらの種類のアイテムの単純な終わりにありますが、特に、異なるJavaScriptエンジンがこれを異なる方法で処理するため、私はそれでも適切だと思います。
2008年

6
私もこれを考えていたので、それは完全に合理的な質問です。
hoju

48
誰かが簡単な質問をしたことで愚痴をこぼしたすべてのために、引き戻してください。これはGoogleでの最初のヒットの1つであり、回答をすばやく参照するのに役立ちました。OPありがとうございます。

40
興味深いことに(または恐ろしいことに)IE 8 alert([1, 2, 3, ].length)では、「4」が表示されることがわかりました。
Daniel Earwicker

回答:


250

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

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


2
私はすべてのJSコード(同じ行の項目の前のコンマ)でこのフォーマットを使用し始めました。これはまさにこのためです。余分な末尾のカンマを見つけやすくなり、時間を大幅に節約できます。面倒です。Firefoxでこのエラーをスローするオプションがあればいいのですが(デバッグに役立つため)。
ロケットモンキー、2011

47
ECMA5がトレーリングを指定するのは本当に残念ですが、JSONはそうではありません。
FlavorScape 2013

4
はい、その余分なラインはほとんど高価ではありませんが、それでも厄介です。
ルネNyffenegger

2
このアプローチは、インデックス付きのforループに対して機能します。for ... inスタイルのループはどうですか?エレガントな方法はありますか?
kgf3JfUtW 2017年

2
プロパティを扱う場合、その余分な1行のコードは複雑になる可能性があります。ifその愚かな小さなコンマを避けるためだけに、たくさんのs を持っていることに気付くかもしれません。高価なYMMVについては、たとえば、これを参照してください。たとえば、jsfiddle.net / oriadam / mywL9384 明確化:あなたのソリューションは素晴らしいです。末尾のコンマを禁止する仕様は嫌いです。
oriadam 2017

133

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

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


1
ECMA 262セクション11.1.5-Object Initialiserで定義するようです。これが良いかどうかは仕様にあるようです。
気晴らしゼロ

6
ECMAScriptが有効であっても、ドキュメントが有効なJSONであるとは限りません。JSONは一般にRFC 4627で定義されおり、その仕様では末尾のコンマは許可されていません。
Tim Gilbert、

1
@ZeroDistraction:ECMA262は、PerlやRuby、C ++、Javaなどのプログラミング言語であるECMAscript(javascriptとも呼ばれます)を定義します。JSONは、XML、CSV、YAMLなどのデータ形式です。彼らは同じものではありません。JSONはEXMA262には存在しませんが、EXMA262から派生した構文は存在し、オブジェクトリテラル表記(JSONではON)と呼ばれます。
slebetman 2016年

106

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

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

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


1
これは、私がこのような状況で通常行うことです。代替のアプローチ(stackoverflow.com/a/201856/8946)で値の前にコンマを追加するために必要な条件を排除することで、追加の割り当てはオフセット以上のものだと思います。
Lawrence Dol 2013

5
スコープを汚染する別の変数があるため、このソリューションは好きではありません。1つifは把握しやすいです。しかし、共有してくれてありがとう。
2015年

3
また、それは、セパレータの範囲を含んでいた方がよいでしょう:for(let ..., sep=""; ... ; sep=",") { ...
ローレンスDolの

1
最近のCPUには優れた分岐予測ロジックがありますが、条件を回避するため、このアプローチが好きです。参照ソートされていない配列よりもソートされた配列を処理する方が速いのはなぜですか?
ホセイン

21

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


1
問題なくIE 11で試してみました。テストしたIEのバージョンのうち、問題の原因となっているのはどこですか。
iconoclast

10
クロックフォードのよ​​うに思えるので、良いものを手に入れることができません。
それと

OPが疑似コードのようにC ++を使用したときにWebブラウザーについて言及するのはなぜですか?OPの質問がWebブラウザーまたはJavaScriptに関連しているとは考えられません。
カウリネーター、

@cowlinator J AVA S CRIPT O bject Nの otation
forresthopkinsa

1
JavaScriptオブジェクトリテラルはフォーマットに影響を与えましたが、JSONはJavascriptエンジン用ではありません
カウリネーター

13

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

...ループの0番目の反復で実際にループを分割し、末尾のコンマを使用するのではなく、先行するコンマを使用して比較コードの臭いやループ内の実際のパフォーマンスオーバーヘッドを取り除くことができると誰も指摘しなかったのかと思います。提案された他のソリューションよりも実際には短く、単純で、高速です(ループ内に分岐/条件がないため)。

例(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("]");

3
シンプルで高速なコードサンプル。提案された他の回答よりもはるかに優れています。
Trevor Jex

12

PHPプログラマーは、implode()をチェックアウトしたい場合があります。これは、文字列を使用して配列を結合します。

ドキュメントから...

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

2
同様に、JavaScriptにはjoin()があります。ほとんどの言語には同様のメソッドがあり、または同様のメソッドを簡単にコーディングできます。
Dan Burton

16
PHPにはjson_encodeがあり、コンマだけでなく、JSONの作成に関するすべての詳細を処理します。
ブリリアント、

カッコいい!それはJSONにどのように適用され、質問の解決においてOPをどのように支援しますか?「JSONオブジェクトで末尾のコンマを使用できますか?」を覚えておいてください。問題です。
Rockin4Life33

7

興味深いことに、CとC ++の両方(およびC#だと思いますが、よくわかりません)は、特定の理由により、末尾のコンマを明確に許可しています。JavaScriptが彼らの先導に従わなかった理由がわかりません。


13
ECMAは、後続のコンマが次の仕様で許可されることを明示的に指定しています:ejohn.org/blog/bug-fixes-in-javascript-2 JSON!= JSオブジェクトであることを明確にするもう1つの理由。
まぶたがない2008年

PHPでも可能です。私が気に入っているのは、PHPの1つの機能だと思います。; p
iconoclast 2014年

4

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

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

http://json5.org/

https://github.com/aseemk/json5


見栄えはいいが、新しいデータ型を追加しないことは機会を逃したように見える...もちろん、ECMAScript 5の厳密なサブセットでありたいという欲求はそれを強制するが、それでも...
iconoclast 14年

1
また、マルチライン文字列はひどいです。ES6マルチラインを夢見ています。
Marco Sulla

10
いいえ、それは恐ろしいアドバイスです。既存のすべてのJSONライブラリの中で、そのような拡張をサポートするものはほとんどありません。そしてこれらすべては非常に疑わしい「改善」のためのものです。このような新しい偽の拡張機能によって、相互運用性がさらに損なわれないようにしてください。
StaxMan、2015

8
コンマの修正にあなたの人生を費やすことはもっと恐ろしいことだと思います。
user619271 2015

3

ループ内のif分岐を回避するための可能な方法があります。

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

2

よると、クラスJSONArray仕様

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

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

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

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


編集:

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

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

2.3。配列

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

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

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

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


6
与えられた文法規則は、あなたが得ることができる限り正確です。持っている方法はありませんvalue-separatorせずにvalueその隣の権利。また、テキストは非常に具体的です。「値の分離」は、複数の値がある場合にのみ適用できます。したがって、2つの値が隣り合っている場合、それらはコンマを使用して区切られます。値が1つしかない場合(または最後の値のみを確認する場合)は分離されないため、カンマはありません。
Steffen Heil

1

私の過去の経験から、ブラウザによってJSONの末尾のカンマの扱いが異なることがわかりました。

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

これを念頭に置き、準拠コードを記述することは常に優れているという事実を踏まえて、末尾のカンマがないことを確認するために余分な労力を費やすことをお勧めします。

:)


1

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

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

また、PHP 5.2.0以上を使用している場合は、組み込みのJSON APIを使用して応答をフォーマットすることができます。


1

リラックスした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


緩やかなJSONはJSONではないため、技術的には適用できません。
user2864740

rjsonとjsonの間で変換できるため、完全に適用可能です。ワークフローにも簡単に追加できます。
Steven Spungin

これは、下流のコンシューマーがこのnot-JSONを理解していることを前提としています。有効なJSONに変換するには、どちらの場合もコンマを削除する必要があります。
user2864740 2018年

OPは文字列を使用して開始します。文字列は、json objectを使用してJSON.parse、またはを使用してライブラリによって解析できますRJSON.parse。ソースがオブジェクトである場合は同意しますが、ここではそうではありません。質問のどこでdownstreamオブジェクトまたは文字列を消費しているのかまったくわかりません。
Steven Spungin

JSONオブジェクトまたは配列を手動で生成する場合、オブジェクトまたは配列の最後の項目に末尾のコンマを残す方が簡単なことがよくあります。これは[ JSONで ] 許可されますか? " -そう、再び:これは興味深い別の形式であるが、それがされているJSONないとについての質問に技術的には適用されませんJSON。「守る」には何もありません:それは質問XにZの提案です
user2864740

0

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

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


0

推奨されませんが、このようなことを行って解析することはできます。

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


0

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

述べたように、それは許可されていません。しかしJavaScriptではこれは:

var a = Array()
for(let i=1; i<=5; i++) {
    a.push(i)
}
var s = "[" + a.join(",") + "]"

(Firefox、Chrome、Edge、IE11、およびIE9、8、7、5ではletなしで正常に動作します)

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.