Яку структуру JSON використовувати для пар ключових значень?


23

Який формат JSON є кращим вибором для пар ключових значень і чому?

[{"key1": "value1"}, {"key2": "value2"}]

Або:

[{"Name": "key1", "Value": "value1"}, {"Name": "key2", "Value": "value2"}]

Або:

{"key1": "value1", "key2": "value2"}

Перший варіант здається більш компактним і «семантично осмисленим». Другий варіант виглядає більш рівномірно структурованим, що може сприяти його обробці. 3-й варіант здається ще більш семантичним.

Пари ключових значень будуть використовуватися для приєднання довільних даних до якогось іншого елемента. Дані повинні бути серіалізовані як JSON, щоб округлити їх через систему.


3
Якщо ви не вимагаєте замовлення, чому б не розглянути {"key1": "value1", "key2": "value2"}?
kennytm

4
JSON - це вже (нестабільний) словник.
Спікер Кейсі

1
Ваша проблема полягає в тому, що опис є досить широким, щоб сказати, що будь-який з цих форматів буде працювати, і справжнє питання полягає в тому, як спростити його споживання, що залежить від того, якими технологіями користуються клієнти.
сценарій

Ви повинні використовувати найпростіший, що відповідає вашим потребам, сподіваємось, що це буде проста форма об’єкта (№3). Однак якщо ви шукаєте ще більше варіантів, ви можете використовувати два масиви паралельно, один для клавіш і один для значень; це буде майже максимально компактно, але при цьому підтримуються об’єктні ключі та дублюючі ключі (які не підтримуватимуться №3).
Ерік Ейдт

Відповіді:


10

Вибираєте ви перший чи третій варіант, залежить від Вашого випадку використання. Якщо ви моделюєте безліч різних екземплярів одного типу речей, виберіть перший. Наприклад, у вас є список людей. Якщо ви моделюєте багато різних атрибутів однієї речі, виберіть третю. Ви можете мати повторні клавіші в першому форматі, але не в третьому.

Другий варіант - жахливий, і я ще не знайшов для цього відповідного випадку використання. Причина, яка страшна, окрім того, що вона є більш багатослівною, полягає в тому, що для однорівневого JSON він порушує автоматичне перетворення більшості бібліотек у словник / карту. Для глибоко вкладеного JSON він розбиває XPath- інтерфейс запитів.

Це змушує працювати з болем. І якщо ви не знаєте своїх ключів під час компіляції, вам потрібен словник або XPath інтерфейс, оскільки ви не зможете перетворити його в клас. Зараз це може не здатися великою справою, але чим довше у вас буде формат даних, тим важче буде змінити.


5
Великою перевагою другого варіанту є те, що він працює з нестроковими клавішами, зокрема складовими клавішами.
CodesInChaos

1
Другий варіант жахливий, і ви ще не повинні знайти справу для використання? Масив словників з багатьма парами ключів / значень повинен мати приблизно найпоширеніший формат для передачі декількох об'єктів.
gnasher729

2
@ Gnasher729, в вашому «найпоширеніший формат» випадку реальні ключі знаходяться на стороні лівої руки: [{"key1": "value1", "key2": "value2"}]. Другий формат - це поставити справжній ключ праворуч і за допомогою іншого клавіші під назвою "Ім'я" вказати на реальний ключ, що робить надзвичайно важким розбір зі стандартними інструментами.
Карл Білефельдт

Я дам вам це, @CodesInChaos. Навіть там, мабуть, це буде дуже особливий випадок. Я ніколи не бачив потреби в цьому в дикій природі.
Карл Білефельдт

3
Вибачте, але це погана відповідь. Другий варіант як дуже часто використовується, так і радиться. Це забезпечує гнучкість клавіш, дозволяє розширити (з більшим полем значення / метаданих), не порушуючи споживачів, і може зберегти порядок елементів. Крім того, наведені причини є хибними: він не порушує жодного "автоматичного перетворення" (він просто поважає презентацію автора як масив), і він прекрасно працює з XPath-подібним інтерфейсом запитів. Єдиний мінус - це підвищена багатослівність.
Hejazzman

5

3-й формат взагалі найкращий. Однак ось приклад чогось придатного для першого формату:

[{
  "username": "foo",
  "id": 1
}, {
  "username": "bar",
  "id": 2
}, {
  "username": "baz",
  "id": 3
}]

Тут кожен об'єкт посилається на окрему річ (і кожен об’єкт використовує ті самі ключі, що й інші, тому їх неможливо було об’єднати). Однак кожен об’єкт у списку зберігається як { "username": "foo", "id": 1 }швидше, ніж [{ "username": "foo" }, { "id": 1 }]тому, що 1) він коротший і 2) він посилається на одну річ з іменем користувача та ідентифікатором, а не на одну річ з іменем користувача та іншу річ з ідентифікатором.

Проблема другого варіанту полягає в тому, що він стає дуже багатослівним як JSON, так і з ним працювати. Однак його можна використовувати, якщо вам потрібно зберігати метаінформацію про об’єкт. Приклад:

{
  "key": "foo",
  "value": 1,
  "mutable": true
}

Тут mutableйдеться про гіпотетичний випадок того, чи можна змінювати саме властивість, а не батьківський об'єкт. Метаінформація на кшталт цієї схожа на JavaScript Object.defineProperty, яка зберігає "налаштовану", "перелічену" та "записувану" інформацію про властивість.


Я намагався використовувати перший формат для деякого JSON, який я надсилав до кінцевої точки C # REST, і він не перетворювався на об’єкт словника. Перетворення його в 3-й формат очистило це.
фіз

5

Ви кажете, що це пари ключ / значення. У цьому випадку використовуйте №3: словник пар ключів / значень.

Якщо це не пара «ключ / значення», тоді не називайте їх «ключами» та «значеннями», а використовуйте №2 - масив словників з довільним вмістом.

Структура №1 є просто складною, якщо вам не потрібні пари ключів / значень, але і їх порядок. Що ти рідко робиш.


3

Поставте себе у взуття людини, яка отримує json. Якщо я не знаю ім'я ключа, як я повинен отримати його в першому чи останньому форматі? Звичайно, ви можете пройти цикл через json, але оскільки всі три формати досягають однакового результату, це лише питання синтаксису. Я думаю, що це єдине змістовне питання: якщо ви знаєте ключові назви, перший чи останній варіант є більш компактними, якщо ні, то другий вибір є більш зрозумілим.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.