L'ordre des éléments dans une liste JSON est-il conservé?

254

J'ai remarqué que l'ordre des éléments dans un objet JSON n'était pas l'ordre d'origine.

Qu'en est-il des éléments des listes JSON? Leur commande est-elle maintenue?

user437899
la source

Réponses:

370

Oui, l'ordre des éléments dans les tableaux JSON est conservé. De RFC 7159 -Le format d'échange de données JSON (JavaScript Object Notation) (accent sur le mien):

Un objet est une collection non ordonnée de zéro ou plusieurs paires nom / valeur, où un nom est une chaîne et une valeur est une chaîne, un nombre, un booléen, une valeur nulle, un objet ou un tableau.

Un tableau est une séquence ordonnée de zéro ou plusieurs valeurs.

Les termes "objet" et "tableau" proviennent des conventions de JavaScript.

Certaines implémentations préservent également l'ordre des objets JSON, mais cela n'est pas garanti.

Jeremy Banks
la source
Cependant, j'ai parlé à certains développeurs qui ont rencontré des problèmes où les tableaux ne sont PAS commandés. Jetez un œil à ce passage étrangement rédigé dans ecma-international.org/publications/files/ECMA-ST/ECMA-404.pdf 'La syntaxe JSON ne définit aucune signification spécifique à l'ordre des valeurs. Cependant, la structure du tableau JSON est souvent utilisée dans des situations où il y a une certaine sémantique dans le classement. '
Cato
74

L'ordre des éléments dans un tableau ( []) est conservé. L'ordre des éléments (nom: paires de valeurs) dans un "objet" ( {}) ne l'est pas, et il est habituel qu'ils soient "mélangés", sinon par le formateur / analyseur JSON lui-même, puis par les objets spécifiques au langage (Dictionary, NSDictionary, Hashtable, etc.) qui sont utilisés comme représentation interne.

Hot Licks
la source
7

En pratique, si les clés étaient de type NaN, le navigateur ne changera pas l'ordre.

Le script suivant affichera "One", "Two", "Three":

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

Alors que le script suivant affichera "Trois", "Un", "Deux":

var foo={"@3":"Three", "@1":"One", "@2":"Two"};
for(bar in foo) {
    alert(foo[bar]);
}
Salam Barbary
la source
16
Mais cela repose sur un comportement indéfini de la part de JSON. Tout ce que vous échangez avec peut ne pas avoir le même comportement.
Hot Licks
3
Cette réponse traite d'un objet. La question concerne la "liste" json, qui ne peut être déduite que de tableau, qui est sémantiquement ordonné par la spécification json (voir la réponse de Jeremy).
Tom
5

Certains moteurs JavaScript gardent les clés dans l'ordre d'insertion. V8, par exemple, conserve toutes les clés dans l'ordre d'insertion, à l'exception des clés qui peuvent être analysées en tant qu'entiers 32 bits non signés .

Cela signifie que si vous exécutez l'une des opérations suivantes:

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

Vous obtiendrez systématiquement chien , ours et singe dans cet ordre, sur Chrome, qui utilise le V8. Node.js utilise également V8. Cela restera vrai même si vous avez des milliers d'articles. YMMV avec d'autres moteurs JavaScript.

Démo ici et ici .

Benjamin Atkin
la source
7
Mais cela repose sur un comportement indéfini de la part de JSON. Tout ce que vous échangez avec peut ne pas avoir le même comportement.
Hot Licks
1

"L'ordre des éléments dans une liste JSON est-il conservé?" n'est pas une bonne question. Vous devez demander "L'ordre des éléments dans une liste JSON est-il maintenu lors de l'exécution [...]?" Comme l'a souligné Felix King, JSON est un format de données textuel. Il ne mute pas sans raison. Ne confondez pas une chaîne JSON avec un objet (JavaScript).

Vous parlez probablement d'opérations comme JSON.stringify(JSON.parse(...)). Maintenant, la réponse est: cela dépend de la mise en œuvre. 99% * des analyseurs JSON ne maintiennent pas l'ordre des objets et maintiennent l'ordre des tableaux, mais vous pourriez aussi bien utiliser JSON pour stocker quelque chose comme

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

et utilisez un analyseur qui maintient l'ordre des objets.

* probablement encore plus :)

user123444555621
la source
1
Faux, du moins si vous parlez de l'utilisation de l'analyseur JSON. La V8 maintient l'ordre, et je suppose que cela représente à lui seul plus de 1% de l'utilisation de l'analyseur JSON. code.google.com/p/v8/issues/detail?id=164#c1
Benjamin Atkin
3
@BenAtkin C'est drôle que votre lien pointe vers l'explication sur la façon dont V8 ne maintient pas la commande.
user123444555621
2
"La norme de facto doit correspondre à l'ordre d'insertion, ce que fait également le V8, mais à une exception près"
Benjamin Atkin
14
Tous les humains sont des hommes, mais à une exception près: les femmes sont des femmes.
user123444555621