Bir JSON nesnesinde sondaki virgül kullanabilir misiniz?


392

Manuel olarak bir JSON nesnesi veya dizisi oluştururken, nesne veya dizideki son öğede bir virgül bırakmak genellikle daha kolaydır. Örneğin, bir dizeden çıkacak kod şöyle görünebilir (C ++ benzeri bir sözde kodda):

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

sana bir ip vermek

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

Buna izin veriliyor mu?


66
Birkaç gün önce internette aramam gereken bir şeydi. Burada SO üzerinde bir cevap görmedim, bu yüzden sitenin misyonunu takip ederek, soruyu sordum ve cevap verdim, böylece diğerleri bulabilirdi. Bu Jeff'in açıkça burada yapmak istediğini söylediği bir şey.
Ben Combee

5
Jeff'in dediği gibi, SO'yu ararken biraz zaman harcamak zorunda olduğunuz şeylerin bir 'defteri' olarak kullanmak mükemmel bir şey. Tabii, bu bu tür öğelerin basit ucunda, ama yine de uygun olduğunu düşünüyorum, çünkü özellikle farklı javascript motorları bununla farklı şekilde ilgilenecektir.
16'da

6
Bunu da merak ediyordum, bu yüzden oldukça makul bir soru.
hoju

48
Birisinin basit bir soru sorduğu tüm orospular için lütfen geri çekilin. Bu, Google'daki ilk isabetlerden biriydi ve yanıtı hızlı bir şekilde referanslamama yardımcı oldu. Teşekkürler OP.

40
İlginç bir şekilde (veya dehşet verici bir şekilde) IE 8'de alert([1, 2, 3, ].length)"4" göstereceğim.
Daniel Earwicker

Yanıtlar:


250

Ne yazık ki JSON belirtimi sondaki virgüllere izin vermiyor. Buna izin verecek birkaç tarayıcı var, ancak genellikle tüm tarayıcılar için endişelenmeniz gerekiyor.

Genel olarak sorunu ters çevirmeye çalışın ve gerçek değerden önce virgül ekleyin, böylece şöyle görünen kodla sonuçlanırsınız:

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

Sizin için döngü içinde ekstra bir kod satırı neredeyse pahalı ...

Bir formun sözlüğünden JSON'a bir yapı çıkardığımda kullandığım başka bir alternatif, her girişten sonra (yukarıda yaptığınız gibi) her zaman bir virgül eklemek ve daha sonra sonunda virgül içermeyen bir kukla giriş eklemektir (ancak bu sadece tembel; ->).

Ne yazık ki bir dizi ile iyi çalışmıyor.


2
Bu biçimlendirmeyi tam olarak bu nedenle tüm JS kodumda (aynı satırda öğeden önce virgül) kullanmaya başladım. Ekstra virgüllerin fark edilmesini kolaylaştırır ve çok zaman kazandırır. Bu can sıkıcı, keşke firefox ile bunun için bir hata atma seçeneği olsaydı (bu hata ayıklamaya yardımcı olur çünkü).
rocketmonkeys

47
ECMA5'in parkurları belirtmesi gerçekten utanç verici ama JSON değil.
FlavorScape

4
Evet, bu ekstra hat neredeyse pahalı değil, ama yine de bir sıkıntı.
René Nyffenegger

2
Bu yaklaşım endeksli döngüler için işe yarar. Peki ... stil döngülerinde? Zarif bir yolu var mı?
kgf3JfUtW

2
Bu ekstra bir kod satırı, özelliklerle uğraşırken karmaşık olabilir. Bu ifaptal küçük virgülden kaçınmak için kendinize tonlarca ton bulabilirsiniz . Pahalılık YMMV hakkında, örneğin bakınız jsfiddle.net/oriadam/mywL9384 Açıklama: Çözümünüz harika, sadece sondaki virgülleri yasaklayan özelliklerden nefret ediyorum.
oriadam

133

Muhafaza olarak sayılı JSON spec http://json.org , virgül arka izin vermez. Gördüğüm kadarıyla, bazı ayrıştırıcılar bir JSON dizesini okurken sessizce onlara izin verirken, diğerleri hatalar atacak. Birlikte çalışabilirlik için dahil etmemelisiniz.

Yukarıdaki kod, dizi sonlandırıcısı eklenirken sondaki virgülün kaldırılması veya öğelerin önüne virgül eklenerek, birincisi için atlanarak yeniden yapılandırılabilir.


1
ECMA 262 11.1.5-Nesne Başlatıcı bölümünde tanımlamak istiyor. Bunun iyi olup olmadığı, spesifikasyonda gibi görünüyor.
Sıfır Oyalama

6
Geçerli bir ECMAScript olması, mutlaka bir belgenin geçerli olduğu anlamına gelmez JSON - JSON genellikle RFC 4627'de tanımlanır ve bu özellik sondaki virgüllere izin vermez.
Tim Gilbert

1
@ZeroDistraction: ECMA262, Perl veya Ruby veya C ++ veya Java gibi bir programlama dili olan ECMAscript'i (javascript olarak da bilinir) tanımlar. JSON, XML veya CSV veya YAML gibi bir veri biçimidir. Aynı şey değiller. EXMA262'de JSON mevcut değil ancak türetildiği sözdizimi yok ve buna Object literal notation (JSON'da ON) deniyor.
slebetman

106

Basit, ucuz, okunması kolay ve özelliklerinden bağımsız olarak her zaman çalışır.

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

$ Delim'e yapılan fazladan ödeme, ödenmesi gereken çok küçük bir fiyattır. Ayrıca, açık bir döngü değil, ayrı kod parçaları varsa da aynı şekilde çalışır.


1
Bu gibi durumlarda genellikle yaptığım şey budur; Alternatif yaklaşımdaki değerden önce virgül eklemek için gereken koşulu ortadan kaldırarak ekstra atamanın ofsetten daha fazla olduğunu hissediyorum ( stackoverflow.com/a/201856/8946 ).
Lawrence Dol

5
Kapsamımı kirleten başka bir değişken olduğu için bu çözümü sevmiyorum. Birini ifkavramak daha kolaydır. Ama paylaştığın için teşekkürler.
Ich

3
Ayrıca, ayırıcının kapsamını dahil etmek daha iyidir:for(let ..., sep=""; ... ; sep=",") { ...
Lawrence Dol

1
Bu yaklaşımı seviyorum çünkü modern CPU'ların iyi şube tahmin mantığı olmasına rağmen koşullardan kaçınıyor. Ayrıca bkz. Sıralı bir diziyi işlemek neden sıralanmamış bir diziden daha hızlı?
Hossein

21

JavaScript'te sondaki virgüllere izin verilir, ancak IE'de çalışmaz. Douglas Crockford'un versiyonsuz JSON spesifikasyonu onlara izin vermedi ve versiyonsuz olduğu için bunun değişmemesi gerekiyordu. ES5 JSON spesifikasyonu onlara bir uzantı olarak izin verdi, ancak Crockford'un RFC 4627'si izin vermedi ve ES5 onları reddetmeye geri döndü. Firefox davayı takip etti. Internet Explorer bu yüzden güzel şeylere sahip olamayız.


1
Ben sadece IE 11 onları sorunsuz çalıştı. Hangi IE sürümlerini test ettiniz, nerede sorunlara neden olduğunu buldunuz?
iconoclast

10
Görünüşe göre Crockford güzel şeylere sahip olamayız. Bu ve JSON
Hejazzman

Neden OP C ++ gibi sahte kod kullandığında web tarayıcılarından bahsedelim? OP'nin sorusunun web tarayıcıları veya JavaScript ile ilgili olması olası değildir.
cowlinator

@cowlinator J Ava S cript O Nesne , N -rotasyon
forresthopkinsa

1
Javascript nesne değişmezleri biçime ilham verdi, ancak JSON Javascript motorları için değil
cowlinator

13

Daha önce de söylendiği gibi, JSON spec (ECMAScript 3 tabanlı) sondaki virgüllere izin vermez. ES> = 5 buna izin verir, bu nedenle bu gösterimi saf JS'de kullanabilirsiniz. Tartışıldı ve bazı ayrıştırıcılar bunu destekledi ( http://bolinfest.com/essays/json.html , http://whereswalden.com/2010/09/08/spidermonkey-json-change-trailing-commas- artık kabul edilmiyor / ), ancak JSON'da çalışmaması gereken özel bir gerçektir ( http://json.org/ ) . O şey dedi ki ...

... Neden hiç kimsenin döngüyü 0'ıncı yinelemede bölebileceğini ve karşılaştırma kodu kokusundan ve döngüdeki herhangi bir gerçek performans yükünden kurtulmak için birini takip etmek yerine önde gelen virgül kullanabileceğinizi belirtti . önerilen diğer çözümlerden daha kısa, daha basit ve daha hızlı bir kod (döngüde dallanma / koşul olmaması nedeniyle).

Örn (OP'nin önerilen koduna benzer bir C stili sözde kodunda):

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
Basit ve hızlı kod örneği. Önerilen diğer cevaplardan çok daha iyi.
Trevor Jex

12

PHP kodlayıcıları implode () 'u kontrol etmek isteyebilir . Bu, bir dizeyi bir dize kullanarak birleştirir.

Gönderen docs ...

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

2
Benzer şekilde, JavaScript join () işlevine sahiptir . Çoğu dil benzer bir yönteme sahiptir veya benzer bir yöntem kolayca kodlanabilir.
Dan Burton

16
PHP json_encode'a sahiptir, bu da sadece virgül değil JSON yapmanın tüm detaylarını idare eder.
Brilliand

Çok havalı! JSON için nasıl uygulanır ve sorularına bir çözüm olarak OP'ye nasıl yardımcı olur? Unutmayın, "Bir JSON nesnesinde sondaki virgül kullanabilir misiniz?" soru.
Rockin4Life33

7

İlginç bir şekilde, hem C & C ++ (ve sanırım C #, ama emin değilim) özellikle sondaki virgül - izin verilen tam nedeni için: Programlı olarak listeleri oluşturma çok daha kolay hale getirir. JavaScript'in neden liderlik etmediğinden emin değilim.


13
ECMA, önümüzdeki spesifikasyonlarda sondaki virgüllere izin verildiğini açıkça belirtmiştir: ejohn.org/blog/bug-fixes-in-javascript-2 JSON! = JS Object.
göz kapaksızlığı

PHP de buna izin verir. Bence PHP'nin beğendiğim tek özelliği. ; p
iconoclast

4

JSON5 kullanın. JSON kullanmayın.

  • Nesneler ve dizilerde virgül olabilir
  • Nesne anahtarları, geçerli tanımlayıcılarsa alıntılanamaz
  • Dizeler tek tırnaklı olabilir
  • Dizeler birden çok satıra bölünebilir
  • Sayılar onaltılık olabilir (taban 16)
  • Sayılar (baştaki veya sondaki) ondalık nokta ile başlayabilir veya bitebilir.
  • Sayılar Infinity ve -Infinity içerebilir.
  • Sayılar açık bir artı (+) işaretiyle başlayabilir.
  • Hem satır içi (tek satır) hem de blok (çok satırlı) yorumlara izin verilir.

http://json5.org/

https://github.com/aseemk/json5


Güzel görünüyor, ancak yeni veri türleri eklememek kaçırılmış bir fırsat gibi görünüyor ... elbette ECMAScript 5'in sıkı bir alt kümesi olma arzusu, ama yine de ...
iconoclast

1
Ayrıca, mutlilin dizeleri korkunç. ES6 çoklu hatlarını hayal ediyorum.
Marco Sulla

10
Hayır, bu KORKUNÇ tavsiyedir. Mevcut tüm JSON kütüphanelerinden çok azı bu uzantıyı desteklemektedir; ve tüm bunlar çok tartışmalı "iyileştirmeler" için. Lütfen bunun gibi yeni sahte uzantılarla çalışabilirliğin daha fazla erozyonuna neden OLMAYIN.
StaxMan

8
Hayatınızı virgül düzeltmeye harcamanın daha korkunç olduğuna inanıyorum.
user619271

3

Döngüde bir if dalından kaçınmanın olası bir yolu vardır.

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

Göre Sınıf JSONArray tarifnamede :

  • Kapatma braketinden hemen önce fazladan (virgül) görünebilir.
  • Boş değer, (virgül) eleme olduğunda eklenir.

Yani, anladığım kadarıyla, yazmasına izin verilmelidir:

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

Ancak bazı ayrıştırıcılar, beklenen 6 yerine 7'yi öğe sayısı olarak (Daniel Earwicker'ın işaret ettiği IE8 gibi) geri gönderebilir.


Düzenlendi:

RFC 4627 (JavaScript Nesne Notasyonu için uygulama / json ortam türü) ve JavaScript dil belirtimine karşı bir JSON dizesini doğrulayan bu JSON Doğrulayıcı buldum . Aslında burada, virgül içeren bir dizi, RFC 4627 belirtimi için değil, yalnızca JavaScript için geçerli kabul edilir.

Bununla birlikte, RFC 4627 spesifikasyonunda:

2.3. Diziler

Bir dizi yapısı, sıfır veya daha fazla değeri (veya öğeyi) çevreleyen köşeli parantez olarak gösterilir. Öğeler virgülle ayrılır.

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

Bana göre bu yine bir yorumlama problemidir. Öğelerin virgülle ayrıldığını yazarsanız (son öğe gibi özel durumlar hakkında bir şey belirtmeden), her iki şekilde de anlaşılabilir.

PS RFC 4627 (açıkça belirtildiği gibi) standart değildir ve zaten (bir teklif standardı) RFC 7159 tarafından obsolited edilir 7159 RFC


6
Verilen dilbilgisi kuralı alabildiğiniz kadar kesin. Yanında value-separatorbir valuehakkı olmayan bir a sahip olmanın yolu yoktur . Ayrıca metin çok özeldir. "Değerlerin ayrılması" yalnızca birden çok değer olduğunda uygulanabilir. Yan yana iki değeriniz varsa, bunlar virgül kullanılarak ayrılır. Bir değeriniz varsa (veya yalnızca sondaki değere bakarsanız), ayrım yoktur, dolayısıyla virgül olmaz.
Steffen Heil

1

Geçmiş deneyimlerime göre, farklı tarayıcıların JSON'daki sondaki virgüllerle farklı şekilde başa çıktığını fark ettim.

Hem Firefox hem de Chrome iyi çalışıyor. Ancak IE (Tüm sürümler) kopmuş gibi görünüyor. Yani senaryonun geri kalanını okumayı bırak.

Bunu akılda tutarak ve aynı zamanda uyumlu kod yazmanın her zaman güzel olduğu gerçeğini göz önünde bulundurarak, sondaki virgül olmadığından emin olmak için ekstra çaba harcamayı öneririm.

:)


1

Mevcut sayımı tutuyorum ve toplam sayımla karşılaştırıyorum. Geçerli sayı toplam sayıdan azsa, virgül görüntülerim.

JSON oluşturma işlemini gerçekleştirmeden önce toplam sayınız yoksa çalışmayabilir.

Daha sonra, PHP 5.2.0 veya daha iyisi kullanıyorsanız, yanıtınızı yerleşik JSON API'sini kullanarak biçimlendirebilirsiniz.


1

Rahat JSON ile, virgül kullanabilirsiniz veya virgülleri dışarıda bırakabilirsiniz . İsteğe bağlıdır.

JSON benzeri bir belgeyi ayrıştırmak için virgüllerin bulunmasına gerek yoktur.

Rahat JSON spesifikasyonuna bir göz atın ve orijinal JSON spesifikasyonunun ne kadar gürültülü olduğunu göreceksiniz. Çok fazla virgül ve alıntı ...

http://www.relaxedjson.org

Örneğinizi bu çevrimiçi RJSON ayrıştırıcısını kullanarak deneyebilir ve doğru şekilde ayrıştırıldığını görebilirsiniz.

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


Rahat JSON JSON teknik olarak uygulanamaz değildir.
user2864740

Rjson'u json'a ve json'dan dönüştürebilirsiniz, bu yüzden tamamen uygulanabilir. İş akışınıza da eklemek çok kolay.
Steven Spungin

Bu, alt tüketicilerin bu JSON olmayanı anladıklarını varsayar. Geçerli JSON'a dönüştürmek, her iki durumda da virgülün kaldırılmasını gerektirir.
user2864740

OP ile başlamak için bir dize kullanılır. Dize bir json objectkullanarak JSON.parseveya kullanılarak bir kitaplıkla ayrıştırılabilir RJSON.parse. Kaynağın bir nesne olup olmadığını kabul ediyorum, ama burada durum böyle değil. Sorunun neresinde bahsettiğini downstreamhiç bir nesne ya da string tüketmiyorum.
Steven Spungin

"Manuel olarak bir JSON nesnesi veya dizisi oluştururken, nesne veya dizideki son öğede bir virgül bırakmak genellikle daha kolaydır. Buna [ JSON'da ] izin veriliyor mu?" - yani, yine: bu ilginç bir alternatif biçim olsa da, JSON değildir ve JSON hakkındaki soruya teknik olarak uygulanamaz . 'Savunmak' için hiçbir şey yok: X'i sorgulamak için bir Z önerisi
user2864740

0

Genellikle dizi üzerinden döngü ve dizesindeki her girişten sonra bir virgül ekleyin. Döngüden sonra son virgülleri tekrar silerim.

Belki en iyi yolu değil, ama her seferinde döngüdeki son nesne olup olmadığını kontrol etmekten daha ucuz.


0

Tavsiye edilmez, ancak yine de ayrıştırmak için böyle bir şey yapabilirsiniz.

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


0

Bir for döngüsü veya benzer yinelenebilir veri yapısı üzerinden yineleme yapmak için for-loop kullanıldığından, dizinin uzunluğunu gösterildiği gibi kullanabiliriz,

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 içeren,

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

0

Belirtildiği gibi izin verilmiyor. Ancak JavaScript'te bu:

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

(Firefox, Chrome, Edge, IE11 ve IE9, 8, 7, 5'de izin verilmeden sorunsuz çalışır)

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.