Вы можете использовать трейлинг-запятые в JSON-объект?



при ручном создании объекта или массива JSON часто проще оставить конечную запятую на последнем элементе объекта или массива. Например, код для вывода из массива строк может выглядеть так (в C++ как псевдокод):



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


даю вам строку типа



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


это разрешено?

786   14  

14 ответов:

к сожалению спецификация JSON не позволяет использовать конечную запятую. Есть несколько браузеров, которые позволят это, но в целом вам нужно беспокоиться обо всех браузерах.

В общем я пытаюсь повернуть проблему вокруг, и добавить запятую перед фактическим значением, так что вы в конечном итоге с кодом, который выглядит так:

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

что дополнительная одна строка кода в вашем цикле for вряд ли стоит дорого...

еще одна альтернатива, которую я использовал при выводе a структура для JSON из словаря некоторой формы должна всегда добавлять запятую после каждой записи (как вы делаете выше), а затем добавлять фиктивную запись в конце, которая не имеет конечной запятой (но это просто лениво ;->).

не работает с массивом, к сожалению.

нет. Спецификация JSON, поддерживаемая в http://json.org, не позволяет завершать запятые. Из того, что я видел, некоторые Парсеры могут молча разрешать их при чтении строки JSON, в то время как другие будут выдавать ошибки. Для совместимости, вы не должны включать его.

приведенный выше код может быть реструктурирован либо для удаления конечной запятой при добавлении Терминатора массива, либо для добавления запятой перед элементами, пропуская это для первого.

простой, дешевый, легкий для чтения, и всегда работает независимо от спецификаций.

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

избыточное назначение $delim-это очень небольшая цена. Также работает так же хорошо, если нет явного цикла, но отдельные фрагменты кода.

конечные запятые разрешены в JavaScript, но не работают в IE. Спецификация Дугласа Крокфорда без версии JSON не позволяла им, и поскольку она была без версии, это не должно было измениться. Спецификация ES5 JSON разрешила их в качестве расширения, но Crockford RFC 4627 не сделал, и ES5 вернулся к их запрещению. Firefox последовал его примеру. Internet Explorer-вот почему у нас не может быть хороших вещей.

PHP кодеры могут захотеть проверить implode (). Это принимает массив соединяет его с помощью строки.

С docs...

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

Как уже было сказано, спецификация JSON (на основе ECMAScript 3) не позволяет завершать запятую. ES >= 5 позволяет это, поэтому вы можете фактически использовать эту нотацию в чистом JS. Об этом уже спорили, и некоторые Парсеры сделал поддержите его (http://bolinfest.com/essays/json.html, http://whereswalden.com/2010/09/08/spidermonkey-json-change-trailing-commas-no-longer-accepted/), но это факт спецификации (как показано на http://json.org/) что это не стоит работа в JSON. Эта штука сказала...

... Мне интересно, почему никто не указал, что вы можете фактически разделить цикл на 0-й итерации и использовать ведущий запятая вместо трейлинга, чтобы избавиться от запаха кода сравнения и любых фактических накладных расходов на производительность в цикле, что приводит к тому, что код на самом деле короче, проще и быстрее (из-за отсутствия ветвления/условных обозначений в цикле), чем другие предлагаемые решения.

например (в a C-стиль псевдокода похож на предложенный ОП код):

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

интересно, что оба C & C++ (и я думаю, что C#, но я не уверен) специально разрешают конечную запятую-именно по этой причине: это делает программную генерацию списков намного проще. Не знаю, почему JavaScript не последовал их примеру.

используйте JSON5. Не используйте JSON.

  • объекты и массивы могут иметь трейлинг-запятые
  • ключи объектов могут быть без кавычек, если они являются допустимыми идентификаторами
  • строки могут быть в одинарных кавычках
  • строки могут быть разбиты на несколько строк
  • числа могут быть шестнадцатеричными (основание 16)
  • числа могут начинаться или заканчиваться десятичной точкой (ведущей или конечной).
  • числа могут включать бесконечность и -Бесконечность.
  • числа могут начинаться с явного знака плюс ( + ).
  • допускаются как встроенные (однострочные), так и блочные (многострочные) комментарии.

http://json5.org/

https://github.com/aseemk/json5

из моего прошлого опыта я обнаружил, что разные браузеры имеют дело с конечными запятыми в JSON по-разному.

и Firefox, и Chrome справляются с этим просто отлично. Но IE (все версии), кажется, ломается. Я имею в виду действительно перерыв и прекратить читать остальную часть сценария.

имея это в виду, а также тот факт, что всегда приятно писать совместимый код, я предлагаю потратить дополнительные усилия на то, чтобы убедиться, что нет конечной запятой.

:)

Я сохраняю текущий счет и сравниваю его с общим счетом. Если текущее число меньше общего числа, я показываю запятую.

может не работать, если у вас нет общего количества до выполнения поколения JSON.

опять же, если вы используете PHP 5.2.0 или лучше, вы можете просто отформатировать свой ответ с помощью встроенного API JSON.

по словам класса JSONArray спецификация:

  • перед закрывающей скобкой может появиться дополнительная (запятая).
  • значение null будет вставлено, когда есть, (запятая) elision.

Итак, как я понимаю, следует разрешить писать:

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

но может случиться так, что некоторые Парсеры вернут 7 как количество элементов (например, IE8, как указал Даниэль Earwicker) вместо ожидаемого 6.


редактировать:

Я нашел это JSON Validator что проверяет строку JSON против RFC 4627 (тип носителя application/json для обозначения объектов JavaScript) и против спецификации языка JavaScript. На самом деле здесь массив с конечной запятой считается допустимым только для JavaScript, а не для спецификации RFC 4627.

однако в спецификации RFC 4627 указано, что:

2.3. Массивы

структура массива представлена в виде квадратных скобок, окружающих ноль или больше значений (или элементов). Элементы разделяются запятыми.

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

для меня это снова проблема интерпретации. Если вы напишете это элементы разделяются запятыми (не говоря ничего об особых случаях, как последний элемент), это можно понять в обоих направлениях.

П. С. в RFC 4627, не стандартная (как явно указано), и уже устарел по RFC 7159 (который является предлагаемым стандартом) RFC 7159

Я обычно перебираю массив и добавляю запятую после каждой записи в строке. После цикла я снова удаляю последнюю запятую.

может быть, не лучший способ, но дешевле, чем проверять каждый раз, если это последний объект в цикле, я думаю.

это не рекомендуется, но вы все равно можете сделать что-то вроде этого, чтобы разобрать его.

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

с расслабленным JSON, вы можете иметь конечные запятые,или просто оставьте запятые. Они необязательны.

нет никакой причины вообще запятые должны присутствовать, чтобы разобрать JSON-подобный документ.

взгляните на расслабленную спецификацию JSON, и вы увидите, насколько "шумно" оригинальная спецификация JSON. Слишком много запятых и кавычек...

http://www.relaxedjson.org

вы также можете попробовать свой пример, используя это онлайн парсер RJSON и посмотреть, как он будет правильно проанализирован.

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

Comments

    Ничего не найдено.