Можете ли вы использовать запятую в объекте JSON?

StackOverflow https://stackoverflow.com/questions/201782

  •  03-07-2019
  •  | 
  •  

Вопрос

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

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

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

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

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

Это было полезно?

Решение

К сожалению спецификация 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 вряд ли будет стоить дорого...

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

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

Другие советы

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

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

Простой, дешевый, легко читаемый и всегда работает независимо от характеристик.

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

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

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

Как уже было сказано, спецификация 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-й итерации и использовать ведущий запятая вместо завершающей единицы, чтобы избавиться от запаха кода сравнения и любых фактических затрат на производительность в цикле, в результате чего код на самом деле короче, проще и быстрее (из-за отсутствия ветвления/условий в цикле), чем другие предложенные решения.

Например.(в псевдокоде в стиле C, аналогичном предлагаемому коду 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("]");

PHP-кодеры могут захотеть проверить взорваться().Для этого требуется объединить массив с помощью строки.

Из документы...

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

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

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

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

http://json5.org/

https://github.com/aseemk/json5

Согласно Спецификация класса JSONArray:

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

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

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

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


Отредактировано:

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

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

2.3.Массивы

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

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

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

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

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

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

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

:)

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

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

Опять же, если вы используете PHP 5.2.0 или более позднюю версию, вы можете просто отформатировать свой ответ, используя встроенный JSON API.

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

Нет никакой необходимости использовать запятые для анализа JSON-подобного документа.

Взгляните на спецификацию Relaxed JSON, и вы увидите, насколько «шумной» является исходная спецификация JSON.Слишком много запятых и кавычек...

http://www.relaxedjson.org

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

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

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

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

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

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

Существует возможный способ избежать ветвления if в цикле.

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

Поскольку цикл for используется для перебора массива или аналогичной итерируемой структуры данных, мы можем использовать длину массива, как показано:

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, содержащим:

 Angela,Baker,2010-05-23
 Betty,Crockett,1990-12-07
 David,Done,2003-10-31
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top