JSON 개체에서 후행 쉼표를 사용할 수 있습니까?
문제
JSON 객체 또는 배열을 수동으로 생성 할 때는 객체 또는 배열의 마지막 항목에 후행 쉼표를 남기는 것이 종종 더 쉽습니다. 예를 들어, 문자열 배열에서 출력하는 코드는 (의사 코드와 유사한 C ++에서)처럼 보일 수 있습니다.
s.append("[");
for (i = 0; i < 5; ++i) {
s.appendF("\"%d\",", i);
}
s.append("]");
당신에게 같은 문자열을 제공합니다
[0,1,2,3,4,5,]
이것이 허용됩니까?
해결책
안타깝게도 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("]");
Loop for Loop의 추가 코드 라인은 거의 비싸지 않습니다 ...
내가 사용한 또 다른 대안은 어떤 형태의 사전에서 JSON에 구조를 출력 할 때 사용한 또 다른 대안은 각 항목 (위에서 수행하는 것처럼) 후에 항상 쉼표를 추가 한 다음 쉼표를 뒤로 옮기지 않는 끝에 더미 항목을 추가하는 것입니다 (그러나 그것은 단지 게으르다;->).
불행히도 배열에서 잘 작동하지 않습니다.
다른 팁
아니요 http://json.org, 후행 쉼표를 허용하지 않습니다. 내가 본 바에 따르면, 일부 파서는 JSON 문자열을 읽을 때 조용히 허용 할 수 있지만 다른 파서는 오류를 던질 수 있습니다. 상호 운용성을 위해서는 포함해서는 안됩니다.
위의 코드는 배열 터미네이터를 추가 할 때 후행 쉼표를 제거하거나 항목 앞에 쉼표를 추가하여 첫 번째 코드를 건너 뛰기 위해 재구성 될 수 있습니다.
단순하고 저렴하며 읽기 쉽고 사양에 관계없이 항상 작동합니다.
$delimiter = '';
for .... {
print $delimiter.$whatever
$delimiter = ',';
}
$ delim에 대한 중복 과제는 지불하기에 매우 적은 가격입니다. 또한 명시적인 루프가 없지만 별도의 코드 조각이없는 경우에도 작동합니다.
이미 말했듯이 JSON SPEC (ECMAScript 3 기반)은 후행 쉼표를 허용하지 않습니다. ES> = 5는 그것을 허용하므로 실제로 해당 표기법을 순수한 JS에서 사용할 수 있습니다. 그것은 논쟁의 여지가 있습니다 했다 지원 (http://bolinfest.com/essays/json.html, http://whereswalden.com/2010/09/08/spidermonkey-json-change-trailing-commas-no-longer-cepted/), 그러나 그것은 사양 사실입니다 ( http://json.org/) 그것은 그 그렇지 않아야합니다 JSON에서 일하십시오. 그게 말했다 ...
... 나는 왜 당신이 실제로 0 번째 반복에서 루프를 분할 할 수 있다는 것을 아무도 지적하지 않았는지 궁금합니다. 주요한 Comma는 비교 코드 냄새와 루프에서 실제 성능 오버 헤드를 제거하기 위해 하나를 추적하는 대신 실제로 제안 된 다른 솔루션보다 실제로 더 짧고 단순하며 빠른 코드를 만듭니다.
EG (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("]");
PHP 코더는 체크 아웃 할 수 있습니다 implode (). 이것은 배열을 사용하여 문자열을 사용하여 결합합니다.
로부터 문서...
$array = array('lastname', 'email', 'phone');
echo implode(",", $array); // lastname,email,phone
흥미롭게도, C & C ++ (그리고 C#이라고 생각하지만 확실하지 않음)는 특히 후행 쉼표를 허용합니다. 정확히 주어진 이유는 다음과 같습니다. 프로그래밍 방식으로 목록을 훨씬 쉽게 생성합니다. JavaScript가 왜 자신의 리드를 따르지 않았는지 잘 모르겠습니다.
JSON5를 사용하십시오. JSON을 사용하지 마십시오.
- 물체와 배열에는 후행 쉼표가있을 수 있습니다
- 객체 키는 유효한 식별자 인 경우 인용 할 수 있습니다
- 문자열은 단일 인용 될 수 있습니다
- 문자열은 여러 줄에 걸쳐 분할 될 수 있습니다
- 숫자는 16 진수 일 수 있습니다 (기본 16)
- 숫자는 소수점으로 시작하거나 끝날 수 있습니다.
- 숫자는 무한대와 -infinity를 포함 할 수 있습니다.
- 숫자는 명시 적 플러스 (+) 부호로 시작할 수 있습니다.
- 인라인 (단일 라인)과 블록 (멀티 라인) 주석이 모두 허용됩니다.
에 따르면 클래스 jsonarray 사양:
- 추가 (쉼표)는 닫는 괄호 바로 앞에 나타날 수 있습니다.
- 널 값은 (comma) elision이있을 때 삽입됩니다.
따라서 이해할 수 있듯이 다음을 쓸 수 있어야합니다.
[0,1,2,3,4,5,]
그러나 일부 파서는 예상 6이 아닌 항목 수 (Daniel Earwicker가 지적한 것처럼 IE8과 같이)로 7을 반환 할 수 있습니다.
편집 :
나는 이것을 찾았다 JSON 유효성 검사기 JSON 문자열을 확인합니다 RFC 4627 (JavaScript 객체 표기법의 응용 프로그램/JSON 미디어 유형) 및 JavaScript 언어 사양에 대해. 실제로 여기에 후행 쉼표가있는 배열은 RFC 4627 사양이 아닌 JavaScript에만 유효한 것으로 간주됩니다.
그러나 RFC 4627에서는 다음과 같습니다.
2.3. 배열
배열 구조는 0 (또는 요소)을 둘러싼 사각형 브래킷으로 표시됩니다. 요소는 쉼표로 분리됩니다.
array = begin-array [ value *( value-separator value ) ] end-array
나에게 이것은 다시 해석 문제이다. 당신이 그것을 쓰면 요소는 쉼표로 분리됩니다 (마지막 요소와 같은 특별한 경우에 대해 언급하지 않고) 두 가지 방법으로 이해할 수 있습니다.
PS RFC 4627은 표준이 아니며 (명시 적으로 명시된대로) RFC 7159 (제안 된 표준)에 의해 이미 쓸모가 있습니다. RFC 7159
과거의 경험에서, 나는 다른 브라우저가 JSON의 후행 쉼표를 다르게 처리한다는 것을 알았습니다.
Firefox와 Chrome은 모두 잘 처리합니다. 그러나 즉, 모든 버전은 깨지는 것 같습니다. 내 말은 정말로 깨지고 나머지 대본을 읽는 것을 중단합니다.
이를 염두에두고 준수 코드를 작성하는 것이 항상 좋은 사실을 염두에두고, 후행 쉼표가 없도록 추가 노력을 기울이는 것이 좋습니다.
:)
나는 현재 수를 유지하고 총 카운트와 비교합니다. 현재 수가 총 카운트보다 작 으면 쉼표가 표시됩니다.
JSON 생성을 실행하기 전에 총 카운트가 없으면 작동하지 않을 수 있습니다.
그런 다음 PHP 5.2.0 이상을 사용하는 경우 JSON API 내장을 사용하여 응답을 형식화 할 수 있습니다.
편안한 JSON을 사용하면 후행 쉼표를 가질 수 있습니다. 아니면 그냥 쉼표를 꺼내십시오. 그들은 선택 사항입니다.
JSON과 같은 문서를 구문 분석하기 위해 모든 쉼표가 존재해야 할 이유가 없습니다.
편안한 JSON 사양을 살펴보면 원래 JSON 사양이 얼마나 '시끄러운'인지 알 수 있습니다. 너무 많은 쉼표와 인용문 ...
이 온라인 RJSON 파서를 사용하여 예제를 시험해 볼 수 있으며 올바르게 구문 분석 할 수 있습니다.
http://www.relaxedjson.org/docs/converter.html?source=%5B0%2C1%2C2%2C3%2C4%2C5%2C%5D
나는 일반적으로 배열 위로 반복하고 문자열의 모든 항목 후에 쉼표를 부착합니다. 루프 후 마지막 쉼표를 다시 삭제합니다.
아마도 가장 좋은 방법은 아니지만 루프의 마지막 개체인지마다 확인하는 것보다 저렴합니다.
권장되지는 않지만 여전히 이와 같은 작업을 수행하여 구문 분석 할 수 있습니다.
jsonStr = '[0,1,2,3,4,5,]';
let data;
eval('data = ' + jsonStr);
console.log(data)
루프에서 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
For-Loop은 배열 또는 유사한 반복 가능한 데이터 구조를 반복하는 데 사용되므로 표시된대로 배열의 길이를 사용할 수 있습니다.
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