Können Sie ein abschließendes Komma in einem JSON-Objekt verwenden?


392

Beim manuellen Generieren eines JSON-Objekts oder -Arrays ist es häufig einfacher, ein abschließendes Komma für das letzte Element im Objekt oder Array zu hinterlassen. Beispielsweise könnte Code, der aus einem Array von Zeichenfolgen ausgegeben werden soll, wie folgt aussehen (in einem C ++ - ähnlichen Pseudocode):

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

Geben Sie eine Zeichenfolge wie

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

Ist das erlaubt?


66
Es war etwas, das ich vor ein paar Tagen im Internet nachschlagen musste. Ich habe hier auf SO keine Antwort gesehen. Als ich der Mission der Site folgte, stellte ich die Frage und beantwortete sie, damit andere sie finden konnten. Dies ist etwas, was Jeff ausdrücklich gesagt hat, er wollte es hier tun.
Ben Combee

5
Wie Jeff sagte, finde ich es vollkommen in Ordnung, SO als "Notizbuch" für Dinge zu verwenden, bei denen man einige Zeit nachschlagen musste. Sicher, dies ist am einfachen Ende dieser Art von Elementen, aber ich denke immer noch, dass es angemessen ist, zumal verschiedene Javascript-Engines dies unterschiedlich behandeln werden.
pkaeding

6
Ich habe mich auch gefragt, also ist es eine absolut vernünftige Frage.
Hoju

48
Für all die Schlampen, denen jemand eine einfache Frage gestellt hat, ziehen Sie sich bitte zurück. Dies war einer der ersten Treffer bei Google und hat mir geholfen, die Antwort schnell zu finden. Vielen Dank, dass Sie OP.

40
Interessanterweise (oder schrecklich) in IE 8 habe ich gerade festgestellt, dass alert([1, 2, 3, ].length)"4" angezeigt wird.
Daniel Earwicker

Antworten:


250

Leider lässt die JSON-Spezifikation kein nachfolgendes Komma zu. Es gibt einige Browser, die dies zulassen, aber im Allgemeinen müssen Sie sich um alle Browser kümmern.

Im Allgemeinen versuche ich, das Problem umzukehren und das Komma vor dem tatsächlichen Wert einzufügen, sodass Sie am Ende Code erhalten, der folgendermaßen aussieht:

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

Diese zusätzliche Codezeile in Ihrer for-Schleife ist kaum teuer ...

Eine andere Alternative, die ich bei der Ausgabe einer Struktur aus einem Wörterbuch irgendeiner Form an JSON verwendet habe, besteht darin, nach jedem Eintrag ein Komma anzuhängen (wie oben beschrieben) und am Ende einen Dummy-Eintrag hinzuzufügen, der kein nachfolgendes Komma enthält (aber das ist nur faul; ->).

Funktioniert leider nicht gut mit einem Array.


2
Ich habe aus genau diesem Grund begonnen, diese Formatierung in meinem gesamten JS-Code (Komma vor Element in derselben Zeile) zu verwenden. Erleichtert das Erkennen zusätzlicher nachfolgender Kommas erheblich und spart viel Zeit. Es ist ärgerlich, ich wünschte, es gäbe eine Option, mit Firefox einen Fehler zu machen (da dies beim Debuggen helfen würde).
Rocketmonkeys

47
Es ist wirklich eine Schande, dass ECMA5 Trailings spezifiziert, JSON jedoch nicht.
FlavorScape

4
Ja, diese zusätzliche Leitung ist kaum teuer, aber dennoch ein Ärgernis.
René Nyffenegger

2
Dieser Ansatz funktioniert für indizierte for-Schleifen. Wie wäre es mit ... in Style-Loops? Gibt es einen eleganten Weg?
kgf3JfUtW

2
Diese zusätzliche Codezeile kann beim Umgang mit Eigenschaften kompliziert sein. Möglicherweise haben Sie Tonnen von ifs, nur um dieses dumme kleine Komma zu vermeiden. Informationen zum Preis von YMMV finden Sie beispielsweise in jsfiddle.net/oriadam/mywL9384. Erläuterung : Ihre Lösung ist großartig. Ich hasse nur Spezifikationen, die ein nachfolgendes Komma verbieten.
Oriadam

133

Nein. Die JSON-Spezifikation, wie sie unter http://json.org gepflegt wird , erlaubt keine nachgestellten Kommas. Nach allem, was ich gesehen habe, können einige Parser sie beim Lesen einer JSON-Zeichenfolge stillschweigend zulassen, während andere Fehler auslösen. Aus Gründen der Interoperabilität sollten Sie es nicht einschließen.

Der obige Code könnte umstrukturiert werden, entweder um das nachfolgende Komma beim Hinzufügen des Array-Terminators zu entfernen oder um das Komma vor Elementen hinzuzufügen, wobei das Komma für das erste übersprungen wird.


1
ECMA 262 Scheint es in Abschnitt 11.1.5-Object Initialiser zu definieren. Ob dies gut ist oder nicht, scheint in der Spezifikation zu sein.
Null Ablenkung

6
Gültiges ECMAScript bedeutet nicht unbedingt, dass ein Dokument gültig ist. JSON - JSON ist im Allgemeinen in RFC 4627 definiert , und diese Spezifikation lässt das nachfolgende Komma nicht zu.
Tim Gilbert

1
@ZeroDistraction: ECMA262 definiert ECMAscript (auch als Javascript bekannt), eine Programmiersprache wie Perl oder Ruby oder C ++ oder Java. JSON ist ein Datenformat wie XML oder CSV oder YAML. Sie sind nicht dasselbe. JSON ist in EXMA262 nicht vorhanden, aber die Syntax, von der es abgeleitet ist, funktioniert und wird als Object-Literal-Notation (ON in JSON) bezeichnet.
Slebetman

106

Einfach, billig, leicht zu lesen und funktioniert immer unabhängig von den Spezifikationen.

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

Die redundante Zuordnung zu $ ​​delim ist ein sehr geringer Preis. Funktioniert auch genauso gut, wenn es keine explizite Schleife gibt, sondern separate Codefragmente.


1
Das ist es, was ich normalerweise in solchen Situationen mache. Ich bin der Meinung, dass die zusätzliche Zuweisung mehr als ausgeglichen wird, indem die Bedingung entfernt wird, die zum Anhängen des Kommas vor dem Wert im alternativen Ansatz erforderlich ist ( stackoverflow.com/a/201856/8946 ).
Lawrence Dol

5
Ich mag diese Lösung nicht, da es eine andere Variable gibt, die meinen Bereich verschmutzt. Man ifist leichter zu erfassen. Aber danke fürs Teilen.
Ich

3
Es ist auch besser, den Umfang des Trennzeichens einzuschließen:for(let ..., sep=""; ... ; sep=",") { ...
Lawrence Dol

1
Ich mag diesen Ansatz, weil er Bedingungen vermeidet, obwohl moderne CPUs eine gute Verzweigungsvorhersagelogik haben. Siehe auch Warum ist es schneller, ein sortiertes Array zu verarbeiten als ein unsortiertes Array?
Hossein

21

Nachgestellte Kommas sind in JavaScript zulässig, funktionieren jedoch nicht im IE. Douglas Crockfords versionlose JSON-Spezifikation erlaubte es ihnen nicht, und da es versionlos war, sollte sich dies nicht ändern. Die ES5-JSON-Spezifikation erlaubte sie als Erweiterung, Crockfords RFC 4627 jedoch nicht, und ES5 ließ sie nicht mehr zu. Firefox folgte dem Beispiel. Internet Explorer ist der Grund, warum wir keine schönen Dinge haben können.


1
Ich habe sie gerade in IE 11 ohne Probleme ausprobiert. In welchen IE-Versionen haben Sie getestet, wo Sie festgestellt haben, dass sie Probleme verursachen?
Bilderstürmer

10
Crockford scheint der Grund zu sein, warum wir keine schönen Dinge haben können. Das und Kommentare in JSON
Hejazzman

Warum Webbrowser erwähnen, wenn das OP C ++ wie Pseudocode verwendet? Es ist unwahrscheinlich, dass sich die Frage des OP auf Webbrowser oder JavaScript bezieht.
Cowlinator

@cowlinator J ava S cript O bject N otation
forresthopkinsa

1
Javascript-Objektliterale haben das Format inspiriert, aber JSON ist nicht für Javascript-Engines
geeignet

13

Wie bereits erwähnt, erlaubt die JSON-Spezifikation (basierend auf ECMAScript 3) kein nachfolgendes Komma. ES> = 5 erlaubt es, so dass Sie diese Notation tatsächlich in reinem JS verwenden können. Es wurde darüber gestritten und einige Parser haben es unterstützt ( http://bolinfest.com/essays/json.html , http://whereswalden.com/2010/09/08/spidermonkey-json-change-trailing-commas- nicht mehr akzeptiert / ), aber es ist die spezielle Tatsache (wie auf http://json.org/ gezeigt ), dass es in JSON nicht funktionieren sollte . Das Ding sagte ...

... Ich frage mich, warum niemand darauf hingewiesen hat, dass Sie die Schleife bei der 0. Iteration tatsächlich teilen und ein führendes Komma verwenden können, anstatt ein nachfolgendes Komma zu verwenden, um den Geruch des Vergleichscodes und den tatsächlichen Leistungsaufwand in der Schleife zu beseitigen Ein Code, der tatsächlich kürzer, einfacher und schneller ist (da keine Verzweigungen / Bedingungen in der Schleife vorhanden sind) als andere vorgeschlagene Lösungen.

ZB (in einem Pseudocode im C-Stil ähnlich dem von OP vorgeschlagenen Code):

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
Einfaches und schnelles Codebeispiel. Viel besser als Lösungen, die andere Antworten vorgeschlagen haben.
Trevor Jex

12

PHP-Codierer möchten möglicherweise implode () auschecken . Dies erfordert, dass ein Array es mithilfe einer Zeichenfolge zusammenfügt.

Aus den Dokumenten ...

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

2
Ebenso hat JavaScript join () . Die meisten Sprachen haben eine ähnliche Methode oder eine ähnliche kann leicht codiert werden.
Dan Burton

16
PHP hat json_encode, der alle Details der Erstellung von JSON behandelt, nicht nur Kommas.
Brilliand

Das ist cool! Wie trifft es auf JSON zu und wie hilft es dem OP bei einer Lösung seiner Frage? Denken Sie daran: "Können Sie in einem JSON-Objekt ein nachfolgendes Komma verwenden?" ist die Frage.
Rockin4Life33

7

Interessanterweise erlauben sowohl C als auch C ++ (und ich denke, C #, aber ich bin nicht sicher) speziell das nachfolgende Komma - genau aus dem angegebenen Grund: Es erleichtert das programmgesteuerte Generieren von Listen erheblich. Ich bin mir nicht sicher, warum JavaScript ihrem Beispiel nicht gefolgt ist.


13
ECMA hat ausdrücklich angegeben, dass nachfolgende Kommas in der kommenden Spezifikation zulässig sind : ejohn.org/blog/bug-fixes-in-javascript-2 Ein weiterer Grund, um klar zu machen, dass JSON! = JS Object.
Augenlidlosigkeit

PHP erlaubt es auch. Ich denke, es ist die einzige Funktion von PHP, die ich mag. ; p
Bilderstürmer

4

Verwenden Sie JSON5. Verwenden Sie kein JSON.

  • Objekte und Arrays können nachgestellte Kommas haben
  • Objektschlüssel können nicht in Anführungszeichen gesetzt werden, wenn sie gültige Bezeichner sind
  • Zeichenfolgen können in einfache Anführungszeichen gesetzt werden
  • Zeichenfolgen können auf mehrere Zeilen aufgeteilt werden
  • Zahlen können hexadezimal sein (Basis 16)
  • Zahlen können mit einem (führenden oder nachfolgenden) Dezimalpunkt beginnen oder enden.
  • Zahlen können Infinity und -Infinity enthalten.
  • Zahlen können mit einem expliziten Pluszeichen (+) beginnen.
  • Es sind sowohl Inline- (einzeilige) als auch Blockkommentare (mehrzeilig) zulässig.

http://json5.org/

https://github.com/aseemk/json5


Sieht gut aus, aber das Hinzufügen neuer Datentypen scheint eine verpasste Gelegenheit zu sein ... natürlich erzwingt der Wunsch, eine strikte Teilmenge von ECMAScript 5 zu bleiben, dies, aber dennoch ...
Bilderstürmer

1
Auch Mutliline-Saiten sind schrecklich. Ich träume von ES6 Multilines.
Marco Sulla

10
Nein, das ist ein schrecklicher Rat. Von allen vorhandenen JSON-Bibliotheken unterstützen nur sehr wenige eine solche Erweiterung. und das alles für sehr fragwürdige "Verbesserungen". Bitte verursachen Sie KEINE weitere Erosion der Interoperabilität durch neue Scheinerweiterungen wie diese.
StaxMan

8
Ich glaube, dass es schrecklicher ist, sein Leben damit zu verbringen, Kommas zu fixieren.
user619271

3

Es gibt eine Möglichkeit, eine if-Verzweigung in der Schleife zu vermeiden.

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

Gemäß der Class JSONArray-Spezifikation :

  • Ein zusätzliches (Komma) wird möglicherweise kurz vor der schließenden Klammer angezeigt.
  • Der Nullwert wird eingefügt, wenn (Komma-) Elision vorliegt.

So wie ich es verstehe, sollte es erlaubt sein zu schreiben:

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

Es kann jedoch vorkommen, dass einige Parser die 7 als Anzahl der Elemente (wie IE8, wie Daniel Earwicker hervorhob) anstelle der erwarteten 6 zurückgeben.


Bearbeitet:

Ich habe diesen JSON-Validator gefunden , der eine JSON-Zeichenfolge gegen RFC 4627 validiert (den Medientyp application / json für die JavaScript-Objektnotation) und gegen die JavaScript-Sprachspezifikation . Tatsächlich wird hier ein Array mit einem nachgestellten Komma nur für JavaScript und nicht für die RFC 4627-Spezifikation als gültig angesehen.

In der RFC 4627-Spezifikation wird jedoch Folgendes angegeben:

2.3. Arrays

Eine Array-Struktur wird als eckige Klammern dargestellt, die null oder mehr Werte (oder Elemente) umgeben. Elemente werden durch Kommas getrennt.

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

Für mich ist dies wieder ein Interpretationsproblem. Wenn Sie schreiben, dass Elemente durch Kommas getrennt sind (ohne etwas über Sonderfälle wie das letzte Element anzugeben), kann dies auf beide Arten verstanden werden.

PS RFC 4627 ist kein Standard (wie ausdrücklich angegeben) und wird bereits von RFC 7159 (einem vorgeschlagenen Standard) RFC 7159 überholt


6
Die angegebene Grammatikregel ist so genau wie möglich. Es gibt keine Möglichkeit, ein value-separatorohne ein valueRecht daneben zu haben. Auch der Text ist sehr spezifisch. "Wertetrennung" kann nur angewendet werden, wenn mehrere Werte vorhanden sind. Wenn Sie also zwei Werte nebeneinander haben, werden diese durch ein Komma getrennt. Wenn Sie einen Wert haben (oder nur den Wert am Ende betrachten), gibt es keine Trennung, daher kein Komma.
Steffen Heil

1

Aufgrund meiner bisherigen Erfahrungen habe ich festgestellt, dass verschiedene Browser mit nachgestellten Kommas in JSON unterschiedlich umgehen.

Sowohl Firefox als auch Chrome handhaben das einwandfrei. Aber IE (alle Versionen) scheint zu brechen. Ich meine wirklich brechen und aufhören, den Rest des Drehbuchs zu lesen.

In Anbetracht dessen und der Tatsache, dass es immer schön ist, kompatiblen Code zu schreiben, empfehle ich, den zusätzlichen Aufwand zu betreiben, um sicherzustellen, dass kein nachgestelltes Komma vorhanden ist.

:) :)


1

Ich behalte eine aktuelle Zählung und vergleiche sie mit einer Gesamtzählung. Wenn die aktuelle Anzahl kleiner als die Gesamtzahl ist, zeige ich das Komma an.

Funktioniert möglicherweise nicht, wenn Sie vor dem Ausführen der JSON-Generierung keine Gesamtzahl haben.

Wenn Sie PHP 5.2.0 oder besser verwenden, können Sie Ihre Antwort einfach mit der integrierten JSON-API formatieren.


1

Mit Relaxed JSON können Sie nachgestellte Kommas verwenden oder die Kommas einfach weglassen . Sie sind optional.

Es gibt überhaupt keinen Grund, warum Kommas vorhanden sein müssen, um ein JSON-ähnliches Dokument zu analysieren.

Werfen Sie einen Blick auf die Relaxed JSON-Spezifikation und Sie werden sehen, wie laut die ursprüngliche JSON-Spezifikation ist. Viel zu viele Kommas und Anführungszeichen ...

http://www.relaxedjson.org

Sie können Ihr Beispiel auch mit diesem Online-RJSON-Parser ausprobieren und sehen, ob es korrekt analysiert wird.

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


Entspanntes JSON ist nicht technisch nicht anwendbar.
user2864740

Sie können rjson in und von json konvertieren, sodass es vollständig anwendbar ist. Sehr einfach, es auch zu Ihrem Workflow hinzuzufügen.
Steven Spungin

Dies setzt voraus, dass nachgeschaltete Verbraucher diesen Nicht-JSON verstehen. Für die Konvertierung in gültigen JSON muss in beiden Fällen das Komma entfernt werden.
user2864740

OP verwendet zunächst eine Zeichenfolge. Die Zeichenfolge kann zu einer json objectVerwendung JSON.parseoder von einer Bibliothek unter Verwendung analysiert werden RJSON.parse. Ich würde Ihnen zustimmen, wenn die Quelle ein Objekt wäre, aber das ist hier nicht der Fall. Ich sehe nicht, wo in der Frage überhaupt erwähnt wird downstream, dass ein Objekt oder eine Zeichenfolge verbraucht wird.
Steven Spungin

"Wenn Sie ein JSON- Objekt oder -Array manuell generieren , ist es oft einfacher, ein abschließendes Komma für das letzte Element im Objekt oder Array zu hinterlassen. Ist dies [ in JSON ] zulässig ?" - also nochmal: Dies ist zwar ein interessantes alternatives Format, aber es ist kein JSON und technisch nicht anwendbar auf die Frage nach JSON . Es gibt nichts zu "verteidigen": Es ist ein Z-Vorschlag, X in Frage zu stellen.
user2864740

0

Normalerweise durchlaufe ich das Array und füge nach jedem Eintrag in der Zeichenfolge ein Komma hinzu. Nach der Schleife lösche ich das letzte Komma wieder.

Vielleicht nicht der beste Weg, aber billiger als jedes Mal zu überprüfen, ob es das letzte Objekt in der Schleife ist, denke ich.


0

Es wird nicht empfohlen, aber Sie können trotzdem so etwas tun, um es zu analysieren.

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


0

Da eine for-Schleife verwendet wird, um über ein Array oder eine ähnliche iterierbare Datenstruktur zu iterieren, können wir die Länge des Arrays wie gezeigt verwenden:

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

Mit datafile.txt enthält,

 Angela,Baker,2010-05-23
 Betty,Crockett,1990-12-07
 David,Done,2003-10-31

0

Wie gesagt ist es nicht erlaubt. In JavaScript ist dies jedoch:

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

(funktioniert gut in Firefox, Chrome, Edge, IE11 und ohne die Erlaubnis in IE9, 8, 7, 5)

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.