496

When manually generating a JSON object or array, it's often easier to leave a trailing comma on the last item in the object or array. For example, code to output from an array of strings might look like (in a C++ like pseudocode):

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

giving you a string like

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

Is this allowed?

18
  • 84
    It was something I needed to lookup up on the web a few days ago. I didn't see an answer here on SO, so in following the mission of the site, I posed the question and answered it so others could find it. This is something Jeff explicitly said he wanted done here. Commented Oct 14, 2008 at 16:16
  • 11
    As Jeff did say, I think its perfectly fine to use SO as a 'notebook' of things that you had to spend some time looking up. Sure, this is on the simple end of those types of items, but I still think its appropriate, especially since different javascript engines will deal with this differently. Commented Oct 14, 2008 at 16:31
  • 7
    I was also wondering this, so it's a perfectly reasonable question. Commented Oct 29, 2009 at 5:02
  • 61
    Interestingly (or horrifyingly) in IE 8 I've just found that alert([1, 2, 3, ].length) will display "4". Commented Mar 4, 2010 at 9:36
  • 8
    Agreed that this is a good question to post. I got here by googling the question. Commented Sep 23, 2011 at 15:12

21 Answers 21

330

Unfortunately the JSON specification does not allow a trailing comma. There are a few browsers that will allow it, but generally you need to worry about all browsers.

In general I try turn the problem around, and add the comma before the actual value, so you end up with code that looks like this:

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

That extra one line of code in your for loop is hardly expensive...

Another alternative I've used when output a structure to JSON from a dictionary of some form is to always append a comma after each entry (as you are doing above) and then add a dummy entry at the end that has not trailing comma (but that is just lazy ;->).

Doesn't work well with an array unfortunately.

Sign up to request clarification or add additional context in comments.

15 Comments

I've started using this formatting in all my JS code (comma before item on same line) for exactly this reason. Makes extra trailing commas much easier to spot, and saves a lot of time. It's annoying, I wish there were an option to throw an error for this with firefox (since that would help with debugging).
Its really a shame that ECMA5 specifies trailings, but JSON don't.
Yes, that extra line is hardly expensive, but a nuisance nevertheless.
This approach works for indexed for-loops. How about for...in style loops? Is there an elegant way?
That extra one line of code can be complicated when dealing with properties. You may find yourself having tons of ifs just to avoid that stupid little comma. About expensiveness YMMV, see this for example jsfiddle.net/oriadam/mywL9384 Clarification: Your solution is great, I just hate specs that forbid a trailing comma.
|
157

No. The JSON spec, as maintained at http://json.org, does not allow trailing commas. From what I've seen, some parsers may silently allow them when reading a JSON string, while others will throw errors. For interoperability, you shouldn't include it.

The code above could be restructured, either to remove the trailing comma when adding the array terminator or to add the comma before items, skipping that for the first one.

3 Comments

ECMA 262 Seems to define it in section 11.1.5-Object Initialiser. Whether or not this is good, seems to be in the spec.
Being valid ECMAScript doesn't necessarily mean a document is valid JSON - JSON is generally defined in RFC 4627, and that spec does not allow the trailing comma.
@ZeroDistraction: ECMA262 defines ECMAscript (also known as javascript) which is a programming language like Perl or Ruby or C++ or Java. JSON is a data format like XML or CSV or YAML. They are not the same thing. JSON doesn't exist in EXMA262 but the syntax it's derived from does and it's called the Object literal notation (the ON in JSON).
121

Simple, cheap, easy to read, and always works regardless of the specs.

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

The redundant assignment to $delim is a very small price to pay. Also works just as well if there is no explicit loop but separate code fragments.

5 Comments

That's what I typically do in situations like this; I feel the extra assignment is more than offset by eliminating the conditional needed for appending the comma before the value in the alternative approach (stackoverflow.com/a/201856/8946).
I don't like this solution, as there is another variable polluting my scope. One if is easier to grasp. But thanks for sharing.
Also, it's better to contain the scope of the separator: for(let ..., sep=""; ... ; sep=",") { ...
I like this approach because it avoid conditionals, although modern CPUs have got good branch prediction logic. See also Why is it faster to process a sorted array than an unsorted array?
Alternately, you can handle the first loop iteration above the loop and then the loop handles 2nd and subsequent iterations if there is reason to. That avoids wasting ANY CPU time. That's easier to do in some languages than others.
28

Trailing commas are allowed in JavaScript, but don't work in IE. Douglas Crockford's versionless JSON spec didn't allow them, and because it was versionless this wasn't supposed to change. The ES5 JSON spec allowed them as an extension, but Crockford's RFC 4627 didn't, and ES5 reverted to disallowing them. Firefox followed suit. Internet Explorer is why we can't have nice things.

5 Comments

I just tried them in IE 11 with no problem. Which versions of IE have you tested in, where you found them to cause problems?
Seems like Crockford is why we can't have nice things. That and comments in JSON
Why mention web browsers when the OP used C++ like pseudocode? It is unlikely that the OP's question is related to web browsers or JavaScript.
@cowlinator JavaScript Object Notation
Javascript object literals inspired the format, but JSON isn't for Javascript engines
20

As it's been already said, JSON spec (based on ECMAScript 3) doesn't allow trailing comma. ES >= 5 allows it, so you can actually use that notation in pure JS. It's been argued about, and some parsers did support it (http://bolinfest.com/essays/json.html, http://whereswalden.com/2010/09/08/spidermonkey-json-change-trailing-commas-no-longer-accepted/), but it's the spec fact (as shown on http://json.org/) that it shouldn't work in JSON. That thing said...

... I'm wondering why no-one pointed out that you can actually split the loop at 0th iteration and use leading comma instead of trailing one to get rid of the comparison code smell and any actual performance overhead in the loop, resulting in a code that's actually shorter, simpler and faster (due to no branching/conditionals in the loop) than other solutions proposed.

E.g. (in a C-style pseudocode similar to OP's proposed 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("]");

1 Comment

Simple and fast code sample. Much better than solutions other answers proposed.
17

Rather than engage in a debating club, because there are bigger problems to be solved, I would adhere to the principle of Defensive Programming by combining two simple techniques in order to simplify interfacing with others:

  1. As a developer of an app that receives json data, I'd be relaxed and allow the trailing comma.

  2. When developing an app that writes json, I'd be strict and use one of the clever techniques of the other answers to only add commas between items and avoid the trailing comma.

7 Comments

This is known as Postel's rule: en.wikipedia.org/wiki/Robustness_principle
Unfortunately, it's an incredibly bad idea. You should implement specifications exactly and reject all non-conforming inputs loudly. The robustness principle leads to dozens of implementations all doing subtly different things, leading to gnashing of teeth. There are multiple ways of input being outside of a specification; no two implementors will extend in exactly the same way. Users will prepare their data against one implementation and then not have it work in another.
@Kaz You certainly have a point. But I get paid for developing working apps, not for apps that stop with error messages complaining about bad input. Bad? Take HTML. If browsers were strict, most sites would stop working. Oops, now I am lured into debating . . .
HTML is precisely the poster example of this. If browsers had been strict from the beginning instead of competing for rendering broken HTML, web standards would have been better off. Your front-end code wouldn't have to handle seven cases for different browsers, that you had to work out through painstaking empiricism.
No problem; for even faster productivity, be sure to use a compiler that silently closes braces for you and such.
|
12

PHP coders may want to check out implode(). This takes an array joins it up using a string.

From the docs...

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

4 Comments

Similarly, JavaScript has join(). Most languages have a similar method, or a similar one can be easily coded.
PHP has json_encode, which handles all the details of making JSON, not just commas.
That's cool! How does it apply to JSON and how does it help out the OP in a resolution to their question? Remember, "Can you use a trailing comma in a JSON object?" is the question.
python has join : ','.join(mylist)
9

Interestingly, both C & C++ (and I think C#, but I'm not sure) specifically allow the trailing comma -- for exactly the reason given: It make programmaticly generating lists much easier. Not sure why JavaScript didn't follow their lead.

2 Comments

ECMA has explicitly specified that trailing commas are allowed in the upcoming spec: ejohn.org/blog/bug-fixes-in-javascript-2 Yet another reason to be clear that JSON != JS Object.
PHP also allows it. I think it's the one feature of PHP that I like. ;p
9

Use JSON5. Don't use JSON.

  • Objects and arrays can have trailing commas
  • Object keys can be unquoted if they're valid identifiers
  • Strings can be single-quoted
  • Strings can be split across multiple lines
  • Numbers can be hexadecimal (base 16)
  • Numbers can begin or end with a (leading or trailing) decimal point.
  • Numbers can include Infinity and -Infinity.
  • Numbers can begin with an explicit plus (+) sign.
  • Both inline (single-line) and block (multi-line) comments are allowed.

http://json5.org/

https://github.com/aseemk/json5

5 Comments

Looks nice, but not adding new data types seems like a missed opportunity... of course the desire to remain a strict subset of ECMAScript 5 forces that, but still...
Also, mutliline strings are terrible. I dream of ES6 multilines.
No, that is HORRIBLE advice. Of all existing JSON libraries, very few support such extension; and all this for very questionable "improvements". Please do NOT cause further erosion of inter-operability by new bogus extensions like this.
I believe that spending your life on fixing commas is more horrible.
@StaxMan true, this is a clear example of standards proliferation
8

No. The "railroad diagrams" in https://json.org are an exact translation of the spec and make it clear a , always comes before a value, never directly before ]:

railroad diagram for array

or }:

railroad diagram for object

Comments

4

There is a possible way to avoid a if-branch in the loop.

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

Comments

2

According to the Class JSONArray specification:

  • An extra , (comma) may appear just before the closing bracket.
  • The null value will be inserted when there is , (comma) elision.

So, as I understand it, it should be allowed to write:

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

But it could happen that some parsers will return the 7 as item count (like IE8 as Daniel Earwicker pointed out) instead of the expected 6.


Edited:

I found this JSON Validator that validates a JSON string against RFC 4627 (The application/json media type for JavaScript Object Notation) and against the JavaScript language specification. Actually here an array with a trailing comma is considered valid just for JavaScript and not for the RFC 4627 specification.

However, in the RFC 4627 specification is stated that:

2.3. Arrays

An array structure is represented as square brackets surrounding zero or more values (or elements). Elements are separated by commas.

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

To me this is again an interpretation problem. If you write that Elements are separated by commas (without stating something about special cases, like the last element), it could be understood in both ways.

P.S. RFC 4627 isn't a standard (as explicitly stated), and is already obsolited by RFC 7159 (which is a proposed standard) RFC 7159

3 Comments

The grammar rule given is as precise as you can get. There is no way to have a value-separator without a value right next to it. Also the text is very specific. "Separation of values" can only apply if there are multiple values. So if you have two values next to each other, they are separated using a comma. If you have one value (or if you only look at the value at the end), there is no separation, hence no comma.
Your sample contains 7 elements, 6 typed integer one void. Stop thinking of this as "trailing" , but more as expressions allowing to be empty or not. Coming from a history of parser building this is really the issue here how many elements in [0, , , ] ? One or four?
In JS, [0,,,4].length is indeed 4, though [0,,,].length is confusingly 3, I guess because 1 trailing comma is discarded? But JSON has no syntax for skipped values, and OP didn't ask "am I allowed to omit a value while still counting as array element?" OP's text & code very clearly asks "am I allowed to terminate all elements with a comma?" — OP's hope is the trailing comma will not affect the parser's idea of array length, not communicate a trailing "void" element. Anyway JSON's answer to both question is NO
1

With Relaxed JSON, you can have trailing commas, or just leave the commas out. They are optional.

There is no reason at all commas need to be present to parse a JSON-like document.

Take a look at the Relaxed JSON spec and you will see how 'noisy' the original JSON spec is. Way too many commas and quotes...

http://www.relaxedjson.org

You can also try out your example using this online RJSON parser and see it get parsed correctly.

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

5 Comments

Relaxed JSON is not JSON so- technically non-applicable.
You can convert rjson to and from json, so it is totally applicable. Very easy to add it to your workflow too.
This makes the assumption that downstream consumers understand this not-JSON. Converting to valid JSON would require removing the comma in either case.
OP uses a string to start with. The string may be parsed to a json object using JSON.parse, or by a library using RJSON.parse. I would agree with you if the source was an object, but that’s not the case here. I do not see where in the question it mentions downstream at all consuming an object or string.
"When manually generating a JSON object or array, it's often easier to leave a trailing comma on the last item in the object or array.. Is this allowed [in JSON]?" - so, again: while this is an interesting alternative format, it is is not JSON and not technically applicable to the question about JSON. There is nothing to 'defend': it's a Z proposal to question X.
1

As stated it is not allowed. But in JavaScript this is:

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

(works fine in Firefox, Chrome, Edge, IE11, and without the let in IE9, 8, 7, 5)

1 Comment

Upvoted for use of high-level .join(), which is cleaner approach than fudging commas within the loop. But there is a caveat: a.push(i) pushes numbers. In JS, join implicitly converts elements to strings, which happens to result in valid json for numbers (except for NaN, Infinity, -Infinity) — but wouldn't be valid if you had strings or nested arrays/objects. In general, each element should be serialized to JSON. In JS, just use JSON.stringify().
0

I usually loop over the array and attach a comma after every entry in the string. After the loop I delete the last comma again.

Maybe not the best way, but less expensive than checking every time if it's the last object in the loop I guess.

Comments

0

From my past experience, I found that different browsers deal with trailing commas in JSON differently.

Both Firefox and Chrome handles it just fine. But IE (All versions) seems to break. I mean really break and stop reading the rest of the script.

Keeping that in mind, and also the fact that it's always nice to write compliant code, I suggest spending the extra effort of making sure that there's no trailing comma.

:)

Comments

0

I keep a current count and compare it to a total count. If the current count is less than the total count, I display the comma.

May not work if you don't have a total count prior to executing the JSON generation.

Then again, if your using PHP 5.2.0 or better, you can just format your response using the JSON API built in.

Comments

0

It is not recommended, but you can still do something like this to parse it.

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

Comments

0

Since a for-loop is used to iterate over an array, or similar iterable data structure, we can use the length of the array as shown,

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

With datafile.txt containing,

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

Comments

0
String l = "[" + List<int>.generate(5, (i) => i + 1).join(",") + "]";

Comments

0

Using a trailing comma is not allowed for json. A solution I like, which you could do if you're not writing for an external recipient but for your own project, is to just strip (or replace by whitespace) the trailing comma on the receiving end before feeding it to the json parser. I do this for the trailing comma in the outermost json object. The convenient thing is then if you add an object at the end, you don't have to add a comma to the now second last object. This also makes for cleaner diffs if your config file is in a version control system, since it will only show the lines of the stuff you actually added.

    char* str = readFile("myConfig.json");
    char* chr = strrchr(str, '}') - 1;
    int i = 0;
    while( chr[i] == ' ' || chr[i] == '\n' ){
        i--;
    }
    if( chr[i] == ',' ) chr[i] = ' ';
    JsonParser parser;
    parser.parse(str);

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.