Czy zachowana jest kolejność elementów na liście JSON?

254

Zauważyłem, że kolejność elementów w obiekcie JSON nie jest pierwotną kolejnością.

Co z elementami list JSON? Czy ich zamówienie jest utrzymane?

użytkownik437899
źródło

Odpowiedzi:

370

Tak, kolejność elementów w tablicach JSON jest zachowana. Z RFC 7159 - Format wymiany danych JavaScript (JSON) Data Interchange Format (moje podkreślenie):

Obiekt to nieuporządkowana kolekcja zer lub więcej par nazwa / wartość, gdzie nazwa jest łańcuchem, a wartością jest łańcuch, liczba, wartość logiczna, null, obiekt lub tablica.

Tablica jest uporządkowaną sekwencją zerową lub większą liczbą wartości.

Terminy „obiekt” i „tablica” pochodzą z konwencji JavaScript.

Niektóre implementacje również zachowują kolejność obiektów JSON, ale nie jest to gwarantowane.

Jeremy Banks
źródło
Jednak rozmawiałem z niektórymi programistami, którzy napotkali problemy, gdy tablice NIE są uporządkowane. Spójrz na ten dziwnie sformułowany fragment w ecma-international.org/publications/files/ECMA-ST/ECMA-404.pdf „Składnia JSON nie definiuje żadnego konkretnego znaczenia dla uporządkowania wartości. Jednak struktura tablic JSON jest często używana w sytuacjach, w których porządkowanie ma pewną semantykę. „
Cato,
73

Zachowana jest kolejność elementów w tablicy ( []). Kolejność elementów (nazwa: pary wartości) w „obiekcie” ( {}) nie jest, i zwykle są one „pomieszane”, jeśli nie przez sam formatyzator / parser JSON, to przez obiekty specyficzne dla języka (Słownik, NSDictionary, Hashtable itp.), Które są używane jako reprezentacja wewnętrzna.

Hot Licks
źródło
7

Praktycznie rzecz biorąc, jeśli klucze byłyby typu NaN, przeglądarka nie zmieni kolejności.

Poniższy skrypt wyświetli „One”, „Two”, „Three”:

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

Podczas gdy następujący skrypt wyświetli „Three”, „One”, „Two”:

var foo={"@3":"Three", "@1":"One", "@2":"Two"};
for(bar in foo) {
    alert(foo[bar]);
}
Salam Barbary
źródło
16
Ale to zależy od nieokreślonego zachowania JSON. Wszystko, z czym się wymienisz, może nie mieć tego samego zachowania.
Hot Licks
3
Ta odpowiedź omawia obiekt. Pytanie dotyczy „listy” json, którą można wywnioskować jedynie na podstawie tablicy, która jest uporządkowana semantycznie według specyfikacji json (patrz odpowiedź Jeremy'ego).
Tom
5

Niektóre silniki JavaScript utrzymują klucze w kolejności wstawiania. Na przykład V8 utrzymuje wszystkie klucze w kolejności wstawiania, z wyjątkiem kluczy, które można analizować jako 32-bitowe liczby całkowite bez znaku .

Oznacza to, że jeśli uruchomisz jedno z poniższych:

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');
}

Będziesz konsekwentnie dostawać psa , niedźwiedzia i małpy w tej kolejności w Chrome, który używa V8. Node.js używa również V8. Będzie to prawdą, nawet jeśli masz tysiące przedmiotów. YMMV z innymi silnikami JavaScript.

Demo tutaj i tutaj .

Benjamin Atkin
źródło
7
Ale to zależy od nieokreślonego zachowania JSON. Wszystko, z czym się wymienisz, może nie mieć tego samego zachowania.
Hot Licks
1

„Czy zachowana jest kolejność elementów na liście JSON?” to nie jest dobre pytanie. Musisz zapytać „Czy kolejność elementów na liście JSON jest zachowywana podczas wykonywania [...]?” Jak zauważył Felix King, JSON jest formatem danych tekstowych. Nie mutuje bez powodu. Nie należy mylić ciągu JSON z obiektem (JavaScript).

Prawdopodobnie mówisz o takich operacjach JSON.stringify(JSON.parse(...)). Teraz odpowiedź brzmi: to zależy od implementacji. 99% * parserów JSON nie utrzymuje kolejności obiektów i utrzymuje porządek tablic, ale równie dobrze możesz użyć JSON do przechowywania czegoś takiego

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

i użyj parsera, który utrzymuje porządek obiektów.

* prawdopodobnie jeszcze więcej :)

użytkownik123444555621
źródło
1
Źle, przynajmniej jeśli mówisz o użyciu parsera JSON. V8 utrzymuje porządek, i przypuszczam, że sam odpowiada za ponad 1% użycia parsera JSON. code.google.com/p/v8/issues/detail?id=164#c1
Benjamin Atkin
3
@BenAtkin To zabawne, że twój link wskazuje na wyjaśnienie, w jaki sposób V8 nie utrzymuje kolejności.
user123444555621,
2
„De facto standardem jest dopasowanie kolejności wstawiania, co robi również V8, ale z jednym wyjątkiem”
Benjamin Atkin
14
Wszyscy ludzie są mężczyznami, ale z jednym wyjątkiem: kobiety są kobietami.
user123444555621,