Сохранен ли порядок элементов в списке JSON?

254

Я заметил, что порядок элементов в объекте JSON не является исходным порядком.

Как насчет элементов списков JSON? Поддерживается ли их порядок?

user437899
источник

Ответы:

370

Да, порядок элементов в массивах JSON сохраняется. Из RFC 7159 - Формат обмена данными JavaScript Object Notation (JSON) (выделено мной):

Объект - это неупорядоченная коллекция из нуля или более пар имя / значение, где имя - это строка, а значение - это строка, число, логическое значение, ноль, объект или массив.

Массив - это упорядоченная последовательность из нуля или более значений.

Термины «объект» и «массив» происходят из соглашений JavaScript.

Некоторые реализации также сохраняют порядок объектов JSON, но это не гарантируется.

Джереми Бэнкс
источник
Однако я говорил с некоторыми разработчиками, которые столкнулись с проблемами, когда массивы НЕ упорядочены. Взгляните на этот странно сформулированный отрывок в ecma-international.org/publications/files/ECMA-ST/ECMA-404.pdf 'Синтаксис JSON не определяет какого-либо конкретного значения для упорядочения значений. Тем не менее, структура массива JSON часто используется в ситуациях, когда есть некоторая семантика для упорядочения. '
Катон
74

Порядок элементов в массиве ( []) сохраняется. Порядок элементов (имя: пары значений) в «объекте» ( {}) отсутствует, и обычно они «перемешиваются», если не самим форматером / анализатором JSON, то объектами, зависящими от языка (Словарь, NSDictionary, Hashtable и т. Д.), Которые используются в качестве внутреннего представления.

Горячие лижет
источник
7

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

Следующий скрипт выведет «One», «Two», «Three»:

var foo={"3":"Three", "1":"One", "2":"Two"};
for(bar in foo) {
    alert(foo[bar]);
}

Тогда как следующий скрипт выведет «Три», «Один», «Два»:

var foo={"@3":"Three", "@1":"One", "@2":"Two"};
for(bar in foo) {
    alert(foo[bar]);
}
Салам Барбари
источник
16
Но это зависит от неопределенного поведения со стороны JSON. Все, с чем вы обмениваетесь, может не иметь такого же поведения.
Hot Licks
3
Этот ответ обсуждает объект. Этот вопрос относится к «списку» json, который может быть выведен только как средний массив, который семантически упорядочен по спецификации json (см. Ответ Джереми).
Том
5

Некоторые механизмы JavaScript поддерживают ключи в порядке вставки. Например, V8 сохраняет все ключи в порядке вставки, за исключением ключей, которые могут быть проанализированы как 32-разрядные целые числа без знака .

Это означает, что если вы выполните одно из следующих действий:

var animals = {};
animals['dog'] = true;
animals['bear'] = true;
animals['monkey'] = true;
for (var animal in animals) {
  if (animals.hasOwnProperty(animal)) {
    $('<li>').text(animal).appendTo('#animals');
  }
}
var animals = JSON.parse('{ "dog": true, "bear": true, "monkey": true }');
for (var animal in animals) {
  $('<li>').text(animal).appendTo('#animals');
}

Вы будете последовательно получать собаку , медведя и обезьяну в этом порядке на Chrome, который использует V8. Node.js также использует V8. Это будет справедливо, даже если у вас есть тысячи предметов. YMMV с другими движками JavaScript.

Демо здесь и здесь .

Бенджамин Аткин
источник
7
Но это зависит от неопределенного поведения со стороны JSON. Все, с чем вы обмениваетесь, может не иметь такого же поведения.
Hot Licks
1

"Поддерживается ли порядок элементов в списке JSON?" не очень хороший вопрос Вы должны спросить: «Поддерживается ли порядок элементов в списке JSON при выполнении [...]?» Как отметил Феликс Кинг, JSON - это текстовый формат данных. Это не мутирует без причины. Не путайте строку JSON с объектом (JavaScript).

Вы, вероятно, говорите о таких операциях, как JSON.stringify(JSON.parse(...)). Теперь ответ: это зависит от реализации. 99% * анализаторов JSON не поддерживают порядок объектов и поддерживают порядок массивов, но вы также можете использовать JSON для хранения чего-то вроде

{
    "son": "David",
    "daughter": "Julia",
    "son": "Tom",
    "daughter": "Clara"
}

и использовать парсер, который поддерживает порядок объектов.

* возможно, даже больше :)

user123444555621
источник
1
Неправильно, по крайней мере, если вы говорите об использовании парсера JSON. V8 поддерживает порядок, и я предполагаю, что на него приходится более 1% использования JSON-анализатора. code.google.com/p/v8/issues/detail?id=164#c1
Бенджамин Аткин
3
@BenAtkin Забавно, что ваша ссылка указывает на объяснение того, как V8 не поддерживает порядок.
user123444555621
2
«Стандарт де-факто должен соответствовать порядку вставки, что и в V8, но с одним исключением»
Бенджамин Аткин
14
Все люди мужчины, но с одним исключением: женщины женщины.
user123444555621