Bisakah Anda menggunakan tanda koma di objek JSON?

392

Saat membuat objek atau array JSON secara manual, seringkali lebih mudah untuk meninggalkan koma pada item terakhir di objek atau array. Sebagai contoh, kode untuk menghasilkan dari array string mungkin terlihat seperti (dalam kode p ++ seperti C ++):

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

memberi Anda string seperti

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

Apakah ini diizinkan?

Ben Combee
sumber
66
Itu adalah sesuatu yang saya butuhkan untuk mencari di web beberapa hari yang lalu. Saya tidak melihat jawaban di sini pada SO, jadi dalam mengikuti misi situs, saya mengajukan pertanyaan dan menjawabnya sehingga orang lain dapat menemukannya. Ini adalah sesuatu yang secara eksplisit dikatakan Jeff ingin dilakukan di sini.
Ben Combee
5
Seperti yang Jeff katakan, saya pikir tidak apa-apa menggunakan SO sebagai 'buku catatan' hal-hal yang harus Anda habiskan untuk mencari. Tentu, ini pada ujung sederhana dari jenis-jenis barang, tetapi saya masih berpikir itu tepat, terutama karena mesin javascript yang berbeda akan menangani hal ini secara berbeda.
pkaeding
6
Saya juga bertanya-tanya, jadi ini pertanyaan yang masuk akal.
hoju
48
Untuk semua orang yang mengeluh bahwa seseorang mengajukan pertanyaan sederhana, silakan mundur. Ini adalah salah satu hit pertama di google, dan itu membantu saya referensi jawabannya dengan cepat. OP terima kasih.
40
Menariknya (atau mengerikan) di IE 8 Saya baru saja menemukan yang alert([1, 2, 3, ].length)akan menampilkan "4".
Daniel Earwicker

Jawaban:

250

Sayangnya spesifikasi JSON tidak memungkinkan tanda koma. Ada beberapa browser yang memungkinkan, tetapi umumnya Anda perlu khawatir tentang semua browser.

Secara umum saya mencoba membalikkan masalah, dan menambahkan koma sebelum nilai aktual, sehingga Anda berakhir dengan kode yang terlihat seperti ini:

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

Satu baris kode tambahan di dalam for loop Anda tidak mahal ...

Alternatif lain yang saya gunakan ketika menampilkan struktur ke JSON dari kamus dari beberapa bentuk adalah selalu menambahkan koma setelah setiap entri (seperti yang Anda lakukan di atas) dan kemudian menambahkan entri boneka di akhir yang belum tertinggal koma (tetapi itu hanya malas; ->).

Sayangnya, tidak berfungsi dengan baik pada array.

brianb
sumber
2
Saya sudah mulai menggunakan format ini di semua kode JS saya (koma sebelum item pada baris yang sama) untuk alasan ini. Membuat koma trailing tambahan jauh lebih mudah dikenali, dan menghemat banyak waktu. Ini menjengkelkan, saya berharap ada opsi untuk melempar kesalahan untuk ini dengan firefox (karena itu akan membantu dengan debugging).
rocketmonkeys
47
Sungguh memalukan bahwa ECMA5 menentukan jejak, tetapi JSON tidak.
FlavourScape
4
Ya, jalur ekstra itu tidak mahal, tapi tetap saja gangguan.
René Nyffenegger
2
Pendekatan ini berfungsi untuk for-loop yang diindeks. Bagaimana dengan ... dalam loop gaya? Apakah ada cara yang elegan?
kgf3JfUtW
2
Tambahan satu baris kode bisa rumit ketika berhadapan dengan properti. Anda mungkin mendapati diri Anda memiliki berton-ton ifhanya untuk menghindari koma kecil yang bodoh itu. Tentang YMMV yang cepat, lihat ini misalnya jsfiddle.net/oriadam/mywL9384 Klarifikasi: Solusi Anda hebat, saya hanya benci spesifikasi yang melarang koma tertinggal.
oriadam
133

Tidak. Spesifikasi JSON, seperti yang dipertahankan di http://json.org , tidak mengizinkan tanda koma. Dari apa yang saya lihat, beberapa parser diam-diam memungkinkan mereka ketika membaca string JSON, sementara yang lain akan melempar kesalahan. Untuk interoperabilitas, Anda tidak harus memasukkannya.

Kode di atas dapat direstrukturisasi, baik untuk menghilangkan koma trailing saat menambahkan terminator array atau untuk menambahkan koma sebelum item, melewatkan itu untuk yang pertama.

Ben Combee
sumber
1
ECMA 262 Tampaknya mendefinisikannya di bagian 11.1.5-Object Initialiser. Apakah ini baik atau tidak, tampaknya ada dalam spesifikasi.
Zero Distraction
6
Menjadi ECMAScript yang valid tidak selalu berarti sebuah dokumen adalah JSON yang valid - JSON secara umum didefinisikan dalam RFC 4627 , dan spesifikasi itu tidak memungkinkan tanda koma.
Tim Gilbert
1
@ZeroDistraction: ECMA262 mendefinisikan ECMAscript (juga dikenal sebagai javascript) yang merupakan bahasa pemrograman seperti Perl atau Ruby atau C ++ atau Java. JSON adalah format data seperti XML atau CSV atau YAML. Mereka bukan hal yang sama. JSON tidak ada di EXMA262 tetapi sintaks yang diturunkannya tidak dan itu disebut notasi objek Object (ON di JSON).
Slebetman
106

Sederhana, murah, mudah dibaca, dan selalu berfungsi terlepas dari spesifikasi.

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

Tugas berlebihan untuk $ delim adalah harga yang sangat kecil untuk dibayar. Juga berfungsi dengan baik jika tidak ada loop eksplisit tetapi fragmen kode terpisah.

Overflowee
sumber
1
Itulah yang biasanya saya lakukan dalam situasi seperti ini; Saya merasa tugas tambahan lebih dari diimbangi dengan menghilangkan persyaratan yang diperlukan untuk menambahkan koma sebelum nilai dalam pendekatan alternatif ( stackoverflow.com/a/201856/8946 ).
Lawrence Dol
5
Saya tidak suka solusi ini, karena ada variabel lain yang mencemari ruang lingkup saya. Seseorang iflebih mudah dipahami. Tapi terima kasih sudah berbagi.
Ich
3
Juga, lebih baik mengandung ruang lingkup pemisah:for(let ..., sep=""; ... ; sep=",") { ...
Lawrence Dol
1
Saya suka pendekatan ini karena menghindari persyaratan, meskipun CPU modern telah mendapat logika prediksi cabang yang baik. Lihat juga Mengapa lebih cepat memproses array yang diurutkan dari pada array yang tidak disortir?
Hossein
21

Tanda koma diizinkan dalam JavaScript, tetapi tidak berfungsi di IE. Spek JSON tanpa versi Douglas Crockford tidak mengizinkannya, dan karena itu bukan versi, ini seharusnya tidak berubah. ES5 JSON spec memungkinkan mereka sebagai perpanjangan, tetapi Crockford's RFC 4627 tidak, dan ES5 kembali untuk melarang mereka. Firefox mengikutinya. Internet Explorer adalah alasan mengapa kita tidak dapat memiliki hal-hal yang baik.

Tobu
sumber
1
Saya baru saja mencobanya di IE 11 tanpa masalah. Versi IE mana yang telah Anda uji, di mana Anda menemukan mereka menyebabkan masalah?
iconoclast
10
Sepertinya Crockford adalah alasan mengapa kita tidak bisa memiliki hal-hal baik. Itu dan komentar di JSON
Hejazzman
Mengapa menyebutkan browser web ketika OP menggunakan C ++ seperti pseudocode? Kecil kemungkinan bahwa pertanyaan OP terkait dengan browser web atau JavaScript.
cowlinator
@cowlinator J ava S cript O bject N otation
forresthopkinsa
1
Literal objek Javascript mengilhami format tersebut, tetapi JSON bukan untuk mesin Javascript
cowlinator
13

Seperti yang sudah dikatakan, spec JSON (berdasarkan ECMAScript 3) tidak mengizinkan trailing koma. ES> = 5 memungkinkannya, jadi Anda benar-benar dapat menggunakan notasi itu di JS murni. Sudah berdebat tentang, dan beberapa parser tidak mendukungnya ( http://bolinfest.com/essays/json.html , http://whereswalden.com/2010/09/08/spidermonkey-json-change-trailing-commas- tidak lagi diterima / ), tetapi itu adalah fakta khusus (seperti yang ditunjukkan pada http://json.org/ ) yang seharusnya tidak berfungsi di JSON. Hal itu mengatakan ...

... Aku bertanya-tanya mengapa tidak ada menunjukkan bahwa Anda benar-benar dapat membagi loop di iterasi 0 dan penggunaan terkemuka koma bukannya tertinggal satu untuk menyingkirkan bau kode perbandingan dan overhead kinerja aktual dalam lingkaran, sehingga kode yang sebenarnya lebih pendek, lebih sederhana dan lebih cepat (karena tidak ada percabangan / kondisional dalam loop) daripada solusi lain yang diajukan.

Misalnya (dalam pseudocode C-style mirip dengan kode yang diusulkan 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("]");

sumber
3
Contoh kode sederhana dan cepat. Jauh lebih baik daripada solusi jawaban lain yang diajukan.
Trevor Jex
12

Coders PHP mungkin ingin memeriksa implode () . Ini membutuhkan array yang bergabung menggunakan string.

Dari dokumen ...

$array = array('lastname', 'email', 'phone');
echo implode(",", $array); // lastname,email,phone
Rik Heywood
sumber
2
Demikian pula, JavaScript telah bergabung () . Sebagian besar bahasa memiliki metode yang sama, atau yang serupa dapat dengan mudah dikodekan.
Dan Burton
16
PHP memiliki json_encode, yang menangani semua detail pembuatan JSON, bukan hanya koma.
Brilliand
Itu keren! Bagaimana ini berlaku untuk JSON dan bagaimana hal itu membantu OP dalam resolusi untuk pertanyaan mereka? Ingat, "Bisakah Anda menggunakan tanda koma di objek JSON?" adalah pertanyaannya.
Rockin4Life33
7

Menariknya, baik C & C ++ (dan saya pikir C #, tapi saya tidak yakin) secara khusus memungkinkan koma tertinggal - untuk alasan yang diberikan: Ini membuat daftar program yang diprogram jauh lebih mudah. Tidak yakin mengapa JavaScript tidak mengikuti jejak mereka.

James Curran
sumber
13
ECMA telah secara eksplisit menentukan bahwa tanda koma diizinkan dalam spec mendatang: ejohn.org/blog/bug-fixes-in-javascript-2 Namun alasan lain untuk menjadi jelas bahwa JSON! = Objek JS.
kelopak mata
PHP juga memungkinkan. Saya pikir itu salah satu fitur PHP yang saya suka. ; p
iconoclast
4

Gunakan JSON5. Jangan gunakan JSON.

  • Objek dan array dapat memiliki tanda koma
  • Kunci objek dapat tidak dikutip jika mereka pengidentifikasi yang valid
  • String dapat dikutip satu kali
  • String dapat dibagi menjadi beberapa baris
  • Angka bisa heksadesimal (basis 16)
  • Angka dapat dimulai atau diakhiri dengan titik desimal (memimpin atau mengikuti).
  • Angka dapat termasuk Infinity dan -Infinity.
  • Angka dapat dimulai dengan tanda plus (+) yang eksplisit.
  • Komentar inline (single-line) dan block (multi-line) diperbolehkan.

http://json5.org/

https://github.com/aseemk/json5

pengguna619271
sumber
Terlihat bagus, tetapi tidak menambahkan tipe data baru sepertinya kesempatan yang terlewatkan ... tentu saja keinginan untuk tetap menjadi bagian yang ketat dari kekuatan ECMAScript 5 yang, tetapi masih ...
iconoclast
1
Juga, string mutliline mengerikan. Saya memimpikan multinines ES6.
Marco Sulla
10
Tidak, itu saran yang MENGERIKAN. Dari semua perpustakaan JSON yang ada, sangat sedikit yang mendukung ekstensi tersebut; dan semua ini untuk "perbaikan" yang sangat dipertanyakan. Tolong, JANGAN menyebabkan erosi interoperabilitas lebih lanjut oleh ekstensi palsu baru seperti ini.
StaxMan
8
Saya percaya bahwa menghabiskan hidup Anda untuk memperbaiki koma lebih mengerikan.
user619271
3

Ada cara yang mungkin untuk menghindari if-branch dalam 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
Zhang Boyang
sumber
2

Menurut spesifikasi Kelas JSONArray :

  • Ekstra, (koma) dapat muncul tepat sebelum braket penutup.
  • Nilai nol akan dimasukkan saat ada, (koma) elision.

Jadi, seperti yang saya pahami, seharusnya diperbolehkan menulis:

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

Tetapi bisa terjadi bahwa beberapa parser akan mengembalikan 7 sebagai jumlah item (seperti IE8 seperti yang ditunjukkan Daniel Earwicker) bukannya 6 yang diharapkan.


Diedit:

Saya menemukan Validator JSON ini yang memvalidasi string JSON terhadap RFC 4627 (Jenis media aplikasi / json untuk Notasi Objek JavaScript) dan terhadap spesifikasi bahasa JavaScript. Sebenarnya di sini array dengan tanda koma dianggap sah hanya untuk JavaScript dan bukan untuk spesifikasi RFC 4627.

Namun, dalam spesifikasi RFC 4627 dinyatakan bahwa:

2.3. Array

Struktur array direpresentasikan sebagai tanda kurung siku yang mengelilingi nol atau lebih nilai (atau elemen). Elemen dipisahkan oleh koma.

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

Bagi saya ini lagi-lagi masalah interpretasi. Jika Anda menulis bahwa Elemen dipisahkan oleh koma (tanpa menyatakan sesuatu tentang kasus khusus, seperti elemen terakhir), itu dapat dipahami dengan dua cara.

PS RFC 4627 bukan standar (seperti yang dinyatakan secara eksplisit), dan sudah usang oleh RFC 7159 (yang merupakan standar yang diusulkan) RFC 7159

Timoty Weis
sumber
6
Aturan tata bahasa yang diberikan setepat yang Anda bisa. Tidak ada cara untuk memiliki value-separatortanpa valuehak sebelahnya. Juga teksnya sangat spesifik. "Pemisahan nilai" hanya dapat berlaku jika ada beberapa nilai. Jadi, jika Anda memiliki dua nilai di samping satu sama lain, mereka dipisahkan menggunakan koma. Jika Anda memiliki satu nilai (atau jika Anda hanya melihat nilai di bagian akhir), tidak ada pemisahan, maka tidak ada koma.
Steffen Heil
1

Dari pengalaman saya sebelumnya, saya menemukan bahwa browser yang berbeda berurusan dengan trailing koma di JSON secara berbeda.

Baik Firefox dan Chrome menanganinya dengan baik. Tapi IE (Semua versi) tampaknya rusak. Maksud saya benar-benar istirahat dan berhenti membaca sisa naskah.

Mengingat hal itu, dan juga fakta bahwa selalu baik untuk menulis kode yang sesuai, saya sarankan menghabiskan upaya ekstra untuk memastikan bahwa tidak ada tanda koma.

:)

dnshio
sumber
1

Saya menyimpan hitungan saat ini dan membandingkannya dengan jumlah total. Jika jumlah saat ini kurang dari jumlah total, saya menampilkan koma.

Mungkin tidak berfungsi jika Anda tidak memiliki jumlah total sebelum mengeksekusi generasi JSON.

Kemudian lagi, jika Anda menggunakan PHP 5.2.0 atau lebih baik, Anda bisa memformat respons Anda menggunakan API JSON bawaan.

eddie
sumber
1

Dengan JSON Santai, Anda dapat memiliki tanda koma, atau biarkan saja koma keluar . Mereka adalah opsional.

Tidak ada alasan sama sekali koma perlu hadir untuk mem-parsing dokumen seperti JSON.

Lihatlah spec JSON Santai dan Anda akan melihat betapa 'berisik' spesifikasi JSON aslinya. Terlalu banyak koma dan kutipan ...

http://www.relaxedjson.org

Anda juga dapat mencoba contoh Anda menggunakan parser RJSON online ini dan melihatnya diurai dengan benar.

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

Steven Spungin
sumber
Santai JSON bukan JSON sehingga secara teknis tidak berlaku.
user2864740
Anda dapat mengonversi rjson ke dan dari json, sehingga benar-benar berlaku. Sangat mudah untuk menambahkannya ke alur kerja Anda juga.
Steven Spungin
Ini membuat asumsi bahwa konsumen hilir memahami ini bukan-JSON. Konversi ke JSON yang valid akan membutuhkan penghapusan koma dalam kedua kasus.
user2864740
OP menggunakan string untuk memulai. String dapat diuraikan menjadi json objectmenggunakan JSON.parse, atau oleh perpustakaan menggunakan RJSON.parse. Saya akan setuju dengan Anda jika sumbernya adalah objek, tapi bukan itu masalahnya. Saya tidak melihat di mana dalam pertanyaan itu disebutkan downstreamsama sekali memakan objek atau string.
Steven Spungin
"Ketika secara manual membuat objek atau array JSON , seringkali lebih mudah untuk meninggalkan tanda koma pada item terakhir dalam objek atau array .. Apakah ini diizinkan [ di JSON ]?" - jadi, sekali lagi: sementara ini adalah format alternatif yang menarik, ini bukan JSON dan tidak secara teknis berlaku untuk pertanyaan tentang JSON . Tidak ada yang perlu 'dipertahankan': ini adalah proposal Z untuk mempertanyakan X.
user2864740
0

Saya biasanya mengulang array dan melampirkan koma setelah setiap entri dalam string. Setelah loop saya menghapus koma terakhir lagi.

Mungkin bukan cara terbaik, tapi lebih murah daripada memeriksa setiap kali apakah itu objek terakhir dalam loop kurasa.

Nils
sumber
0

Tidak disarankan, tetapi Anda masih bisa melakukan hal seperti ini untuk menguraikannya.

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

feibing
sumber
0

Karena for-loop digunakan untuk melakukan iterate pada array, atau struktur data iterable yang serupa, kita dapat menggunakan panjang array seperti yang ditunjukkan,

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

Dengan datafile.txt berisi,

 Angela,Baker,2010-05-23
 Betty,Crockett,1990-12-07
 David,Done,2003-10-31
Gregory Horne 07AD
sumber
0

Sebagaimana dinyatakan itu tidak diizinkan. Namun dalam JavaScript ini adalah:

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

(berfungsi dengan baik di Firefox, Chrome, Edge, IE11, dan tanpa izin di IE9, 8, 7, 5)

theking2
sumber