Puteți utiliza o virgulă într-un obiect JSON?

Atunci când generați manual un obiect sau o matrice JSON, este adesea mai ușor să lăsați o virgulă pe ultima poziție a obiectului sau a matricei. De exemplu, codul de ieșire dintr-o serie de șiruri de caractere ar putea arăta (într-un pseudocod asemănător C ++):

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

oferindu-ți un șir de caractere

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

Este permis acest lucru?

321
Interesant (sau îngrozitor) în IE 8 Tocmai am constatat că alerta ([1, 2, 3,] .length) va afișa "4".
adăugat autor Daniel Earwicker, sursa
Mă întrebam și eu, deci este o întrebare perfect rezonabilă.
adăugat autor hoju, sursa
Ca răspuns la ideea utilizării SO ca marcaj social pentru întrebări comune de programare: ce ar putea fi greșit în ceea ce privește adăugarea de conținut care va aduce în mod inevitabil mai mulți programatori (și expertiza lor) pe site?
adăugat autor dclowd9901, sursa
După cum a spus Jeff, cred că este foarte bine să o folosiți ca pe un "notebook" al lucrurilor pe care trebuia să-i petreceți puțin timp în căutarea. Sigur, acest lucru este la sfârșitul simplu al acestor tipuri de articole, dar eu cred încă că este potrivit, mai ales că motoarele JavaScript diferite se vor ocupa de acest lucru în mod diferit.
adăugat autor pkaeding, sursa
@DanielEarwicker: Irelevant, deoarece nu este JSON.
adăugat autor Lightness Races in Orbit, sursa
Dacă JSON nu este pentru motoarele Javascript, de ce este numele său "notație JavaScript Obiect"?
adăugat autor James Curran, sursa
A fost ceva de care aveam nevoie să caut pe web câteva zile în urmă. Nu am văzut un răspuns aici în legătură cu SO, așadar urmând misiunea site-ului, am pus întrebarea și mi-am răspuns, astfel încât alții să o poată găsi. Acesta este ceva ce Jeff a spus în mod explicit că dorește să facă aici.
adăugat autor Ben Combee, sursa
Mulțumiri! Nu am vrut să-l elimin singur eu.
adăugat autor Ben Combee, sursa
Dar încă un lucru: de ce este OP Manuale scrie JSON? Acesta este un model clar anti-model - ar trebui să folosiți întotdeauna o bibliotecă pentru a genera JSON sau pentru a converti în/din structura obiectului pe care o are limba. Folosirea concatenării String-urilor cere doar probleme; nu doar pentru virgule, ci și pentru codificare, evadare, inciguire incorectă. Este exact la fel de rău ca și utilizarea manipulării String sau regexps pentru XML.
adăugat autor StaxMan, sursa
Cu ceva atât de fundamental încât răspunsul se găsește prin analizarea specurilor oficiale, acest lucru pare mai degrabă să pescuiască puncte decât să ofere răspunsuri utile problemelor nerezolvate. Scuze frate.
adăugat autor eyelidlessness, sursa
Pentru ceea ce merită, plângerea mea nu a fost că întrebarea este simplă (am răspuns cu bucurie la o serie de întrebări simple aici), dar că apare (la prima vedere) o întrebare care vizează punctele de reputație ale jocurilor. Veți observa, de asemenea, că am recunoscut că întrebarea este valabilă după o discuție.
adăugat autor eyelidlessness, sursa
Am eliminat eticheta cu întrebări contradictorii deoarece este evident că acest lucru nu este la fel de bine cunoscut cum ar trebui să fie, în ciuda faptului că este explicit detaliat în spec.
adăugat autor eyelidlessness, sursa
Deoarece literalurile obiectului Javascript au inspirat formatul. Nu credeți că spuneți că motoarele JS încep să aibă capacități JSON construite? simonwillison.net/2006/Dec/20/json Dar JSON nu are multe restricții impuse de JS, de exemplu. Fonturile obiectului JS nu necesită chei indicate.
adăugat autor eyelidlessness, sursa
Mai mult, motoarele JS care o tratează diferit provin din faptul că JS nu (în prezent) înțelege JSON și pur și simplu o tratează ca pe un obiect/array literal. Diferența este o diferență în tratarea motorului a literalurilor obiect/matrice, care nu sunt aceleași cu JSON.
adăugat autor eyelidlessness, sursa
JSON nu este pentru motoarele Javascript, este un format universal de schimb de date. Nu există loc de eroare în răspunsul la întrebare, deoarece este clar specificat.
adăugat autor eyelidlessness, sursa
Dacă eo consolare, nu am coborât, tocmai am adăugat eticheta pentru că am crezut că este potrivit.
adăugat autor eyelidlessness, sursa
Sunt de acord că aceasta este o întrebare bună pentru postare. Am ajuns aici, uitându-mă la întrebarea.
adăugat autor fool4jesus, sursa

14 răspunsuri

Din păcate, specificația JSON nu permite o virgulă în partea de jos. Există câteva browsere care o vor permite, dar, în general, trebuie să vă faceți griji cu privire la toate browserele.

În general, încerc să întorc problema în jur și să adaug virgula înaintea valorii reale, astfel încât să ajungeți la codul care arată astfel:

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

Așa că o singură linie de cod în buclă pentru dvs. este greu de scump ...

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 ;->).

Nu funcționează bine cu o matrice, din nefericire.

179
adăugat
Este într-adevăr o rușine că ECMA5 specifică trailings, dar JSON nu.
adăugat autor FlavorScape, sursa
Sfat mare despre adăugarea unei intrări inactiv la sfârșit!
adăugat autor dcsan, sursa
Da, acea linie suplimentară nu este deloc costisitoare, ci o neplăcere.
adăugat autor René Nyffenegger, sursa
Această abordare funcționează pentru bucle indexate. Ce zici de ... în bucle de stil? Există un mod elegant?
adăugat autor sam, sursa
Dacă vă place codul obfuscated, puteți evita adăugarea suplimentară astfel: s.appendF (& ", \"% d \ "[[i], i); Puteți simplifica acest lucru la "..." +! I , dar compilatorul poate avertiza despre aritmetica șirului.
adăugat autor Marcelo Cantos, sursa
Răspuns bun. furnizați "dovada" (un link către docs, specificații etc.) al răspunsului dvs.
adăugat autor chharvey, sursa
Ei bine, acum am o sarcină de a scrie un arbore de sintaxă într-o formă de JSON în timp ce este generat de o stivă automată. Nu pot folosi acest truc din păcate.
adăugat autor Calmarius, sursa
Există o modalitate de a face Firefox să se comporte ca IE în această privință și să producă o eroare sau cel puțin să avertizeze când se întâlnește o virgulă înclinată? Mă dezvolt în primul rând în Firefox, așa că ar fi frumos să fiu informat despre această problemă cât mai curând posibil.
adăugat autor Michael Butler, sursa
Actualizat răspunsul pentru a răspunde explicit la întrebare. Sunt de acord, răspunsul meu inițial a ignorat explicit, "nu".
adăugat autor brianb, sursa
Această linie suplimentară de cod poate fi complicată atunci când se ocupă de proprietăți. S-ar putea să găsiți că ai tone de dacă e doar pentru a evita acea virgulă proastă. Despre expansivitatea YMMV, a se vedea de exemplu jsfiddle.net/oriadam/mywL9384 Clarificare: soluția ta este minunată , Doar urăsc specificațiile care interzic virgulă.
adăugat autor oriadam, sursa
Am inceput sa folosesc acest format in tot codul meu JS (virgula inainte de articolul pe aceeasi linie) din acest motiv. Efectuează comenzi suplimentare de urmărire mult mai ușor de observat și economisește mult timp. Este enervant, aș vrea să fi existat o opțiune de a arunca o eroare pentru acest lucru cu firefox (deoarece asta ar ajuta la depanare).
adăugat autor rocketmonkeys, sursa

Nu. Specificația JSON, așa cum se menține la http://json.org , nu permite virgulele posterioare. Din ceea ce am văzut, unii parseri le pot permite în tăcere când citesc un șir JSON, în timp ce alții vor arunca erori. Pentru interoperabilitate, nu trebuie să o includeți.

Codul de mai sus ar putea fi restructurat, fie pentru a elimina virgula din urmă atunci când adăugați terminația matricei, fie pentru a adăuga virgula înaintea elementelor, sărind peste cea pentru prima.

113
adăugat
Și acesta este răspunsul corect la întrebare.
adăugat autor cdiggins, sursa
ECMA 262 Se pare că se definește în secțiunea 11.1.5 - Initializatorul de obiecte. Dacă acest lucru este bun sau nu, pare să fie în spec.
adăugat autor Zero Distraction, sursa
@ZeroDistraction: ECMA262 definește ECMAscript (cunoscut și ca javascript), care este un limbaj de programare precum Perl sau ruby sau C ++ sau Java. JSON este un format de date cum ar fi xml sau CSV sau YAML. Nu sunt același lucru. JSON nu există în EXMA262, dar sintaxa derivată de la ea se numește Notă literală obiect (ON în JSON).
adăugat autor slebetman, sursa
Fiind valid ECMAScript nu înseamnă neapărat că un document este valabil JSON - JSON este în general definit în RFC 4627 , iar acest spec. nu permite virgulă de sfârșit.
adăugat autor Tim Gilbert, sursa

Simplu, ieftin, ușor de citit și funcționează întotdeauna indiferent de specificații.

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

Cesiunea redundantă la $ delim este un preț foarte mic de plătit. Funcționează de asemenea la fel de bine dacă nu există o bucla explicită, ci fragmente separate de cod.

96
adăugat
Asta fac de obicei în astfel de situații; Cred că asignarea suplimentară este mai mult decât compensată prin eliminarea condiționării necesare pentru adăugarea virgulei înainte de valoarea din abordarea alternativă ( stackoverflow.com/ o/201856/8946 ).
adăugat autor Lawrence Dol, sursa
De asemenea, este mai bine să conŃinem domeniul separatorului: pentru (let ..., sep = ""; ...; sep = ",") {...
adăugat autor Lawrence Dol, sursa
Nu-mi place această soluție, deoarece există o altă variabilă care mă poluează. Un dacă este mai ușor de înțeles. Dar multumesc pentru partajare.
adăugat autor Ich, sursa

Vinetele de virgulă sunt permise în JavaScript, dar nu funcționează în IE. Douglas Crockford nu a fost de acord cu versiunile JSON și pentru că a fost fără versiune, nu trebuia să se schimbe. Specificația ES5 JSON le-a permis ca o extensie, dar RFC 4627 a lui Crockford nu a făcut-o și ES5 a revenit pentru a le interzice. Firefox a urmat exemplul. Internet Explorer este motivul pentru care nu putem avea lucruri frumoase.

15
adăugat
Tocmai am încercat în IE 11 fără nici o problemă. Pe ce versiuni de IE ați testat, unde le-ați găsit să provoace probleme?
adăugat autor iconoclast, sursa
Pare că Crockford este motivul pentru care nu putem avea lucruri frumoase. Asta și comentariile în JSON
adăugat autor Hejazzman, sursa
adăugat autor Tobu, sursa

Coderii PHP ar putea dori să verifice implode() . Aceasta necesită o matrice care o unește folosind un șir.

Din docs ...

$array = array('lastname', 'email', 'phone');
echo implode(",", $array);//lastname,email,phone
11
adăugat
În mod similar, JavaScript are join() . Cele mai multe limbi au o metodă similară sau o metodă similară poate fi ușor codificată.
adăugat autor Dan Burton, sursa
PHP are json_encode, care gestionează toate detaliile de a face JSON, nu doar virgule.
adăugat autor Brilliand, sursa
Cele mai multe limbi, cu excepția Java.
adăugat autor Robert, sursa

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

... Mă întreb de ce nimeni nu a subliniat că puteți împărți bucla la iterația a 0-a și folosiți virgula conducând în loc de a trage unul pentru a scăpa de mirosul de cod de comparație și de orice performanță reală deasupra capului în bucla, rezultând un cod care este de fapt mai scurt, mai simplu și mai rapid (din cauza lipsei de ramificație/condiționalități în buclă) decât alte soluții propuse.

De exemplu. (într-un pseudocod în stil C similar cu codul propus de OP):

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("]");
8
adăugat

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.

6
adăugat
PHP o permite, de asemenea. Cred că este o singură caracteristică a PHP care îmi place. ; p
adăugat autor iconoclast, sursa
Vinetele de virgulă funcționează în Firefox, dar nu în IE.
adăugat autor kzh, sursa
ECMA a specificat explicit că virgulele urmărite sunt permise în următoarea spec: ejohn.org/blog/bug-fixes-in-javascript-2 Un alt motiv pentru a fi clar că JSON! = JS Object.
adăugat autor eyelidlessness, sursa

Utilizați JSON5. Nu utilizați JSON.

  • Obiectele și matricele pot avea virgule de urmărire
  • Cheile obiectului pot fi necotate dacă sunt identificatori valabili
  • String-urile pot fi citate unic
  • Șirurile pot fi împărțite pe mai multe linii
  • Numerele pot fi hexazecimale (baza 16)
  • Numerele pot să înceapă sau să se termine cu un punct zecimal (înainte sau înapoi).
  • Numerele pot include Infinit și Infinit.
  • Numerele pot începe cu un semn explicit plus (+).
  • Sunt permise atât comentariile inline (cu o singură linie), cât și blocurile (mai multe linii)

http://json5.org/

https://github.com/aseemk/json5

5
adăugat
De asemenea, șirurile mutliline sunt teribile. Visez la multiline ES6.
adăugat autor Marco Sulla, sursa
Arată frumos, dar nu adăugarea de noi tipuri de date pare ca o oportunitate ratată ... Desigur, dorința de a rămâne un subset strict al ECMAScript 5 forțe care, dar încă ...
adăugat autor iconoclast, sursa
Nu, acesta este sfatul HORRIBLE. Dintre toate bibliotecile existente JSON, foarte puțini susțin o astfel de extindere; și toate acestea pentru "îmbunătățiri" foarte discutabile. Vă rugăm să NU provocați o eroziune suplimentară a interoperabilității prin noi extensii false cum ar fi aceasta.
adăugat autor StaxMan, sursa
Cred că vă petreceți viața pe fixarea virgulelor este mai oribilă.
adăugat autor user619271, sursa

Păstrez un număr curent și o comparăm cu un număr total. Dacă numărul curent este mai mic decât numărul total, afișăm virgula.

Poate nu funcționează dacă nu aveți un număr total înainte de executarea generației JSON.

Apoi, din nou, dacă utilizați PHP 5.2.0 sau o versiune mai bună, puteți să formatați răspunsul dvs. utilizând interfața JSON built in.

1
adăugat

Din experiența mea anterioară, am constatat că diferite browsere se ocupă de virgulele din JSON în mod diferit.

Atât Firefox, cât și Chrome se ocupă foarte bine de acestea. Dar IE (Toate versiunile) pare să se rupă. Vreau să spun că pauză și nu mai citiți restul scenariului.

Ținând cont de acest lucru și de faptul că este întotdeauna plăcut să scriem cod conform, vă recomand să cheltuiți efortul suplimentar de a vă asigura că nu există nici o virgulă.

:)

1
adăugat

În conformitate cu caietul de sarcini JSONArray :

  • Un extra, (virgulă) poate apărea chiar înaintea brațului de închidere.
  • Valoarea nulă va fi inserată atunci când există, (comma) elision.

Deci, așa cum înțeleg, ar trebui să li se permită să scrie:

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

Dar s-ar putea întâmpla ca unii parseri să returneze cei 7 ca număr de itemi (cum ar fi IE8, după cum a subliniat Daniel Earwicker) în loc de așteptările 6.


editat:

Am găsit acest Validator JSON care validează un șir JSON împotriva RFC 4627 (tipul de aplicație/json pentru jurnalul de obiect JavaScript) și împotriva specificației limbajului JavaScript. De fapt, o matrice cu o virgulă este considerată validă doar pentru JavaScript și nu pentru caietul de sarcini RFC 4627.

Totuși, în specificația RFC 4627 se menționează că:

2.3. Matricile

     

O structură de matrice este reprezentată sub formă de paranteze pătrate care înconjoară zero   sau mai multe valori (sau elemente). Elementele sunt separate prin virgule.

  array = începutul matricei [value * (value-separator value)] end-array
 

Pentru mine aceasta este din nou o problemă de interpretare. Dacă scrieți Elementele sunt separate prin virgule (fără a spune ceva despre cazuri speciale, cum ar fi ultimul element), ar putea fi înțeleasă în ambele sensuri.

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

1
adăugat
Regula de gramatică dată este la fel de precisă pe cât puteți obține. Nu există nicio modalitate de a avea un separator de valoare fără o valoare chiar lângă ea. De asemenea, textul este foarte specific. "Separarea valorilor" se poate aplica numai dacă există mai multe valori. Deci, dacă aveți două valori una lângă cealaltă, ele sunt separate prin virgulă. Dacă aveți o valoare (sau dacă vă uitați doar la valoarea de la capăt), nu există nici o separare, deci nu virgulă.
adăugat autor Steffen Heil, sursa

Am o buclă de obicei peste matrice și atașez o virgulă după fiecare intrare în șir. După buclă, șterg din nou ultima virgulă.

Poate că nu cel mai bun mod, dar mai puțin costisitor decât verificarea de fiecare dată dacă este ultimul obiect din buclă.

0
adăugat

Cu JSON relaxat, poți să ai virgule în virgulă, sau să părăsești virgulele . Ele sunt opționale.

Nu este nici un motiv să fie prezente virgule pentru a analiza un document asemănător JSON.

Aruncați o privire la speculația Relaxed JSON și veți vedea cât de "zgomotos" este speculația originală JSON. Câte prea multe virgule și citate ...

http://www.relaxedjson.org

De asemenea, puteți încerca exemplul dvs. utilizând acest parser online RJSON și îl puteți vedea parsând corect.

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

0
adăugat

Nu este recomandat, dar puteți face totul în felul acesta pentru al analiza.

<div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false"> <div class="snippet-code">

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

0
adăugat
JavaScript, România - Moldova
JavaScript, România - Moldova
328 participanți

Comunitatea Română JavaScript: github.com/js-ro Pentru confort, opriți notificările. Parteneri: @node_ro, @php_ro, @python_ro, @seo_ro, @RomaniaGroup, @ai_ro, @Grupuri_IT Offtop: @holywars_ro Joburi: @js_jobs_ro Sponsored with ❤️ by ciupacabra.com