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
며칠 전에 웹에서 찾아보아야 할 것이 었습니다. 나는 여기에 대답을 보지 못했기 때문에 사이트의 사명을 수행하면서 다른 사람들이 찾을 수 있도록 질문을 제기하고 대답했습니다. 이것은 Jeff가 여기에서하고 싶다고 명시 적으로 말한 것입니다.
벤 콤비

5
Jeff가 말했듯이, 나는 당신이 찾는 데 시간을 소비해야 할 것들의 '노트북'으로 SO를 사용하는 것이 완벽하다고 생각합니다. 물론, 이것은 이러한 유형의 항목의 단순한 끝에 있지만 여전히 다른 자바 스크립트 엔진이 다르게 처리하기 때문에 적절하다고 생각합니다.
pkaeding

6
나는 또한 이것을 궁금해 했으므로 완벽하게 합리적인 질문입니다.
hoju

48
누군가 간단한 질문을했던 모든 사람들에게 물러서십시오. 이것은 Google의 첫 번째 히트 중 하나였으며 답변을 신속하게 참조하는 데 도움이되었습니다. 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 루프에있는 한 줄의 코드는 거의 비싸지 않습니다 ...

일부 양식의 사전에서 JSON으로 구조를 출력 할 때 사용한 또 다른 대안은 각 항목 뒤에 항상 쉼표를 추가 한 다음 (위에서 수행하는 것처럼) 쉼표가 아닌 끝에 더미 항목을 추가하는 것입니다 (그러나 그것은 게으른;->)입니다.

불행히도 어레이와 잘 작동하지 않습니다.


2
이 이유로 정확하게 모든 JS 코드 (동일한 줄의 항목 앞에 쉼표) 에서이 형식을 사용하기 시작했습니다. 여분의 후행 쉼표를 훨씬 쉽게 찾을 수 있으며 많은 시간을 절약합니다. 성가신 일입니다. 파이어 폭스 (디버깅에 도움이 될 것이므로)로 오류를 발생시키는 옵션이 있었으면 좋겠습니다.
rocketmonkeys

47
ECMA5가 후행을 지정한다는 것은 부끄러운 일이지만 JSON은 그렇지 않습니다.
FlavorScape

4
그렇습니다. 추가 라인은 비싸지 않지만 귀찮은 일입니다.
René Nyffenegger

2
이 방법은 인덱스 된 for 루프에 적용됩니다. 스타일 루프는 어떻습니까? 우아한 방법이 있습니까?
kgf3JfUtW

2
속성을 처리 할 때 여분의 한 줄의 코드가 복잡 할 수 있습니다. 당신은 if그 바보 같은 작은 쉼표를 피하기 위해 수많은 톤을 가지고 있음을 알 수 있습니다 . expensiveness YMMV 정보, 예를 들어이 볼 jsfiddle.net/oriadam/mywL9384 대한 설명 : 귀하의 솔루션은 중대하다, 난 그냥 사양을 미워 금지를 뒤에 쉼표.
oriadam

133

아니요. http://json.org 에서 유지 관리되는 JSON 사양 은 후행 쉼표를 허용하지 않습니다. 내가 본 것에서 일부 파서는 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에 존재하지 않지만이 구문에서 파생 된 구문은 Object 리터럴 표기법 (JSON의 ON)이라고합니다.
slebetman

106

간단하고 저렴하며 읽기 쉽고 사양에 관계없이 항상 작동합니다.

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

$ delim에 대한 중복 할당은 지불하기에 매우 작은 가격입니다. 명시적인 루프는 없지만 별도의 코드 조각이있는 경우에도 잘 작동합니다.


1
이것이 제가 이런 상황에서 일반적으로하는 일입니다. 대체 접근법 ( stackoverflow.com/a/201856/8946 ) 의 값 앞에 쉼표를 추가하는 데 필요한 조건을 제거하여 추가 할당이 오프셋 이상으로 느껴집니다 .
Lawrence Dol

5
내 범위를 오염시키는 또 다른 변수가 있기 때문에이 솔루션을 좋아하지 않습니다. 하나 if는 이해하기 쉽습니다. 공유해 주셔서 감사합니다.
Ich

3
또한 구분 기호의 범위를 포함하는 것이 좋습니다.for(let ..., sep=""; ... ; sep=",") { ...
Lawrence Dol

1
현대 CPU에는 좋은 분기 예측 논리가 있지만 조건을 피하기 때문에이 방법이 마음에 듭니다. 참조 가 빠른 정렬되지 않은 배열보다 정렬 된 배열을 처리하는 데 왜?
Hossein 2019

21

후행 쉼표는 JavaScript에서 허용되지만 IE에서는 작동하지 않습니다. Douglas Crockford의 버전없는 JSON 사양에서는이를 허용하지 않았으며 버전이 없기 때문에 변경되지 않았습니다. ES5 JSON 사양은이를 확장으로 허용했지만 Crockford의 RFC 4627 은 그렇지 않았으며 ES5는이를 허용하지 않기로했습니다. 파이어 폭스가 뒤 따랐다. Internet Explorer는 우리가 좋은 것을 가질 수없는 이유입니다.


1
방금 IE 11에서 문제없이 시도했습니다. 어떤 버전의 IE를 테스트했으며 문제가 발생한 곳은 어디입니까?
iconoclast

10
Crockford처럼 우리가 좋은 것을 가질 수없는 이유입니다. JSON의 의견
Hejazzman

OP가 의사 코드와 같은 C ++을 사용할 때 왜 웹 브라우저를 언급합니까? OP의 질문이 웹 브라우저 또는 JavaScript와 관련이있을 가능성은 없습니다.
cowlinator

@cowlinator J 아바 S cript O bject N의 otation
forresthopkinsa

1
자바 스크립트 객체 리터럴 형식 영감을하지만, JSON은 자바 스크립트 엔진 아니다
cowlinator

13

이미 말했듯이 JSON 사양 (ECMAScript 3 기반)은 후행 쉼표를 허용하지 않습니다. ES> = 5가 허용하므로 실제로 순수 JS에서 해당 표기법을 사용할 수 있습니다. 논쟁이 있었고 일부 파서 그것을 지원했습니다 ( http://bolinfest.com/essays/json.html , http://whereswalden.com/2010/09/08/spidermonkey-json-change-trailing-commas- no-longer-accepted / )이지만 사양 사실입니다 ( http://json.org/에 표시됨) ) 즉, 그것은 JSON에서 작동합니다. 그 말은 ...

... 아무도 아무도 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을 만드는 모든 세부 사항을 처리합니다.
Brilliand

멋지다! JSON에 어떻게 적용되며 질문에 대한 해결책으로 OP를 어떻게 도울 수 있습니까? "JSON 객체에 후행 쉼표를 사용할 수 있습니까?" 질문입니다.
Rockin4Life33

7

흥미롭게도 C & C ++ (그리고 C #이라고 생각하지만 확실하지는 않지만)는 특히 쉼표를 허용합니다. 정확히 이유 : 프로그래밍 방식으로 목록을 훨씬 쉽게 생성합니다. 왜 JavaScript가 그들의 주도를 따르지 않았는지 모르겠습니다.


13
ECMA는 다음 스펙에서 후행 쉼표가 허용되도록 명시 적으로 지정했습니다. ejohn.org/blog/bug-fixes-in-javascript-2 또 다른 이유는 JSON! = JS Object입니다.
eyelidlessness

PHP도 가능합니다. 나는 그것이 내가 좋아하는 PHP의 한 기능이라고 생각합니다. ; p
iconoclast

4

JSON5를 사용하십시오. JSON을 사용하지 마십시오.

  • 객체와 배열은 후행 쉼표를 가질 수 있습니다
  • 유효한 식별자 인 경우 개체 키를 따옴표로 묶을 수 없습니다
  • 작은 따옴표로 묶을 수 있습니다
  • 문자열을 여러 줄로 나눌 수 있습니다
  • 숫자는 16 진수 일 수 있습니다 (밑수 16)
  • 숫자는 (리딩 또는 후행) 소수점으로 시작하거나 끝날 수 있습니다.
  • 숫자에는 무한대와-무한대가 포함될 수 있습니다.
  • 숫자는 명시적인 더하기 (+) 기호로 시작할 수 있습니다.
  • 인라인 (한 줄) 및 블록 (여러 줄) 주석이 모두 허용됩니다.

http://json5.org/

https://github.com/aseemk/json5


멋지게 보이지만 새로운 데이터 유형을 추가하지 않으면 놓친 기회처럼 보입니다. 물론 ECMAScript 5의 엄격한 하위 집합을 유지하려는 욕구는 여전히
그렇습니다

1
또한, 뮤 틀린 문자열은 끔찍합니다. ES6 여러 줄을 꿈꿉니다.
Marco Sulla

10
아뇨, 그건 끔찍한 조언입니다. 기존의 모든 JSON 라이브러리 중에서 이러한 확장을 지원하는 사람은 거의 없습니다. 이 모든 것은 매우 의심스러운 "개선"입니다. 이와 같은 새로운 가짜 확장으로 인해 상호 운용성이 더 이상 침식되지 않도록하십시오.
StaxMan

7
쉼표를 수정하는 데 인생을 보내는 것이 더 끔찍하다고 생각합니다.
user619271

3

루프에서 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

2

클래스 JSONArray 사양 에 따르면 :

  • 닫는 괄호 바로 앞에 추가, (쉼표)가 나타날 수 있습니다.
  • , (쉼표) 제거가 있으면 널값이 삽입됩니다.

따라서 내가 이해할 때 다음과 같이 쓸 수 있어야합니다.

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

그러나 일부 파서가 7을 예상 한 6 대신 항목 수 (예 : Daniel Earwicker가 지적한 IE8)로 반환 할 수 있습니다.


편집 :

RFC 4627 에 대해 JSON 문자열의 유효성 을 검사하는 이 JSON Validator 를 찾았습니다. (JavaScript 객체 표기법의 응용 프로그램 / json 미디어 유형)과 JavaScript 언어 사양에 대해 . 실제로 여기에 후행 쉼표가있는 배열은 RFC 4627 사양이 아닌 JavaScript에만 유효한 것으로 간주됩니다.

그러나 RFC 4627 사양에서는 다음과 같이 명시되어 있습니다.

2.3. 배열

배열 구조는 0 개 이상의 값 (또는 요소)을 둘러싸는 대괄호로 표시됩니다. 요소는 쉼표로 구분됩니다.

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

나에게 이것은 다시 해석 문제이다. 작성하면 Elements는 쉼표로 구분됩니다 마지막 요소와 같은 특수한 경우를 언급하지 않고 두 가지 방식으로 이해할 수 있습니다.

PS RFC 4627은 표준이 아니며 (명백하게 언급 된 바와 같이) RFC 7159 (제안 된 표준) RFC 7159에 의해 이미 암시되어 있습니다.


6
주어진 문법 규칙은 최대한 정확합니다. 을 할 수있는 방법이 없습니다 value-separator없이 value옆에 권리. 또한 텍스트는 매우 구체적입니다. "값 분리"는 여러 값이있는 경우에만 적용 할 수 있습니다. 따라서 서로 옆에 두 개의 값이 있으면 쉼표를 사용하여 구분됩니다. 하나의 값이 있거나 끝 부분의 값만 보는 경우 구분이 없으므로 쉼표가 없습니다.
Steffen Heil

1

과거의 경험을 통해 다른 브라우저가 JSON의 후행 쉼표를 다르게 처리한다는 것을 알았습니다.

Firefox와 Chrome 모두 잘 처리합니다. 그러나 IE (모든 버전)가 깨지는 것 같습니다. 나는 정말로 스크립트의 나머지 부분을 읽고 중단한다는 것을 의미합니다.

이를 염두에두고 준수 코드를 작성하는 것이 항상 좋기 때문에 쉼표가 없는지 확인하는 추가 노력을 기울이십시오.

:)


1

현재 수를 유지하고 총 수와 비교합니다. 현재 카운트가 총 카운트보다 작 으면 쉼표를 표시합니다.

JSON 생성을 실행하기 전에 총 개수가 없으면 작동하지 않을 수 있습니다.

PHP 5.2.0 이상을 사용하는 경우 내장 된 JSON API를 사용하여 응답의 형식을 지정할 수 있습니다.


1

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


편안한 JSON은 기술적으로 적용 할 수없는 JSON이 아닙니다.
user2864740

rjson을 json으로 변환하거나 json에서 변환 할 수 있으므로 완전히 적용 가능합니다. 워크 플로에도 쉽게 추가 할 수 있습니다.
Steven Spungin

이것은 다운 스트림 소비자가 JSON이 아닌 것을 이해한다고 가정합니다. 유효한 JSON으로 변환하려면 두 경우 모두 쉼표를 제거해야합니다.
user2864740

OP는 문자열을 사용하여 시작합니다. 문자열은 json objectusing JSON.parse이나 라이브러리를 사용 하여 구문 분석 할 수 있습니다 RJSON.parse. 소스가 객체 인 경우 동의하지만 여기서는 그렇지 않습니다. 질문 downstream에서 객체 나 문자열을 소비하는 곳을 전혀 언급하지 않았습니다 .
Steven Spungin 1

" 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.