Bagaimana cara mewakili set di JSON?

16

JSON mendukung struktur data berikut (setara Java): Skalar, Array / Daftar, dan Peta.

A Settidak didukung di luar kotak di JSON.

Saya memikirkan beberapa cara untuk mewakili satu set di JSON:

[1] - Sebagai daftar

Namun, daftar memiliki urutannya sendiri, jadi dua daftar berikut, ["a", "b"]dan ["b", "a"]tidak sama dengan daftar, tetapi mereka harus sama dengan set.

[2] - Sebagai peta

Gunakan kunci-set peta, dan abaikan nilainya.

Tetapi sekali lagi, menggunakan perbandingan standar, keduanya tidak sama dengan peta:

{"a": "foo", "b": "bar"}, {"a": null, "b": null}

[3] - Sebagai peta, dengan nilai khusus

Ambil skalar, katakan 0atau nulldan paksakan untuk menjadi nilai setiap kunci di peta:

{"a": 0, "b": 0}

Dengan cara ini, di bawah alat perbandingan standar, objek sama, bahkan jika urutan kunci diubah.

Namun, teknik ini mencemari dokumen JSON dengan data yang tidak relevan.

[4] - Sebagai daftar yang dipesan

Kembali ke saran pertama, tetapi kali ini sebagai daftar yang dipesan. Jenis ini memecahkan masalah perbandingan.

Namun, kami juga harus mempertimbangkan kompleksitas pengurutan, dan juga bahwa notasi peta menangani duplikat, sementara daftar yang diurutkan tidak. Contoh:

{"a": 400, "a": 9}ditangani sebagai {"a": 9}, tetapi ["g", "g"]akan selalu demikian ["g", "g"].

Setelah mengatakan semua itu, tampaknya bagi saya bahwa notasi daftar lebih jelas, tetapi notasi peta lebih kuat untuk duplikasi kunci, dan membuatnya lebih sulit untuk konsisten tentang nilai khusus (meskipun nullsepertinya pilihan yang baik untuk itu).

Bagaimana menurut anda? Bagaimana Anda mewakili satu set di JSON?

PS

Perhatikan bahwa pertanyaan ini hanya tentang JSON. Saya tahu bahwa format lain, seperti yaml, tersedia. Masih...

Ron Klein
sumber
1
Set tidak didukung oleh JSON, itu di luar ruang lingkup. Satu set, atau koleksi yang berbeda dan unik, ada dalam ruang lingkup aplikasi. Karena ini merupakan koleksi, akan lebih jelas untuk menggunakan sintaksis koleksi.
Zymus
1
Mengapa Anda ingin mewakili set di JSON? Ingat JSON adalah format pertukaran.
Andres F.
@AndresF. Saya pikir itu akan menjadi ide bagus untuk mengekspresikan atribut keunikan dari nilai-nilai tersebut. Saya tidak akan mengikat JSON hanya dengan format pertukaran. Ini juga dapat berguna untuk penyimpanan dokumen (seperti di MongoDB).
Ron Klein
@RonKlein Cukup adil. Tapi ugh ... jangan mulai dengan MongoDB: P
Andres F.
Dalam YAML, set direpresentasikan sebagai opsi Anda [3], tetapi memiliki notasi khusus yang tidak dimiliki JSON.
Jasmijn

Jawaban:

21

Anda tidak bisa. Seperti yang Anda katakan, Anda dapat mewakili array dan kamus. Anda punya dua pilihan.

Mewakili set sebagai array. Keuntungan: Konversi dari set ke array dan kembali biasanya mudah. Kekurangan: Array memiliki urutan tersirat, yang tidak ditetapkan oleh set, jadi mengonversi set identik ke array JSON dapat membuat array yang akan dianggap berbeda. Tidak ada cara untuk menegakkan bahwa elemen array adalah unik, sehingga array JSON mungkin tidak berisi set yang valid (jelas Anda bisa mengabaikan duplikat; itulah yang kemungkinan akan terjadi).

Mewakili set sebagai kamus, dengan nilai arbitrer per kunci, misalnya 0 atau nol. Jika Anda mengabaikan nilai-nilainya, ini adalah pasangan yang sempurna. Di sisi lain, Anda mungkin tidak memiliki dukungan pustaka untuk mengekstrak kunci kamus sebagai set, atau untuk mengubah set menjadi kamus.

Dalam lingkungan pemrograman saya, konversi antara set dan array lebih mudah (array untuk mengatur akan kehilangan nilai duplikat, yang seharusnya tidak ada di sana, atau akan dianggap benar), jadi untuk alasan itu saya akan pergi dengan array. Tapi itu masalah pendapat.

TETAPI: Ada gajah besar yang gemuk di ruangan yang belum disebutkan. Kunci dalam kamus JSON hanya bisa berupa string. Jika set Anda bukan serangkaian string, maka Anda hanya memiliki pilihan untuk menggunakan array.

gnasher729
sumber
5
kasus tepi non-string adalah argumen yang bagus terhadap kamus.
Ron Klein
4

Jangan mencoba mewakili set di JSON. Lakukan itu saat mem-parsing data saja.

Data JSON Anda harus memiliki skema yang menentukan bidang mana yang harus diperlakukan sebagai set, atau Anda mungkin memiliki metadata yang disematkan dalam data JSON itu sendiri yang menjelaskan kapan daftar harus diperlakukan sebagai set (misalnya {"houses": {"_type": "set", "value": [...]}}) atau dengan konvensi penamaan.

Perhatikan bahwa menurut standar JSON, objek JSON dapat memiliki kunci duplikat. Susunan kata ECMA-404:

Benda

[...] Sintaks JSON tidak memberlakukan batasan pada string yang digunakan sebagai nama, tidak mengharuskan string nama menjadi unik, dan tidak memberikan signifikansi apa pun pada urutan pasangan nama / nilai. Ini semua adalah pertimbangan semantik yang dapat ditentukan oleh prosesor JSON atau dalam spesifikasi yang mendefinisikan penggunaan spesifik JSON untuk pertukaran data.

AFAICD, tidak ada dalam spec yang melarang nama yang tidak unik, dan ada banyak implementasi parser JSON yang dapat menguraikan nama objek yang tidak unik. RFC 7159 mencegah nama-nama yang tidak unik untuk interoperabilitas, tetapi secara khusus tidak melarangnya juga, dan melanjutkan ke daftar bagaimana berbagai parser terlihat menangani nama-nama objek yang tidak unik.

Dan ECMA 404 juga tidak mengharuskan pemesanan array dipertahankan:

Array

Sintaks JSON tidak mendefinisikan arti khusus apa pun untuk urutan nilai. Namun, struktur array JSON sering digunakan dalam situasi di mana ada beberapa semantik untuk pemesanan.

Kata-kata ini memungkinkan aplikasi untuk menggunakan array untuk mewakili set jika mereka memilihnya.

Lie Ryan
sumber