JSON 列表中元素的顺序是不是保留?

Posted

技术标签:

【中文标题】JSON 列表中元素的顺序是不是保留?【英文标题】:Is the order of elements in a JSON list preserved?JSON 列表中元素的顺序是否保留? 【发布时间】:2011-11-05 01:41:42 【问题描述】:

我注意到 JSON 对象中元素的顺序不是原始顺序。

JSON 列表的元素呢?他们的秩序是否得到维护?

【问题讨论】:

【参考方案1】:

是的,JSON 数组中元素的顺序被保留。来自RFC 7159 -The javascript Object Notation (JSON) Data Interchange Format (强调我的):

对象是零个或多个名称/值的无序集合 对,其中名称是字符串,值是字符串、数字、 布尔值、空值、对象或数组。

数组是零个或多个值的有序序列。

术语“对象”和“数组”来自于 JavaScript。

一些实现也确实保留了 JSON 对象的顺序,但这不能保证。

【讨论】:

但是,我已经与一些遇到过数组未排序问题的开发人员交谈过。看看ecma-international.org/publications/files/ECMA-ST/ECMA-404.pdf 中这段措辞奇怪的段落,“JSON 语法没有为值的排序定义任何特定含义。但是,JSON 数组结构通常用于排序有一些语义的情况。 ' @Cato 这段话并不意味着数组可能是无序的。这意味着对数组进行排序的原因可能是未知的,因为您没有指定对其进行排序的原因。【参考方案2】:

保持数组 ([]) 中元素的顺序。 “对象”()中的元素(名称:值对)的顺序不是,而且它们通常是“混乱”的,如果不是由 JSON 格式化程序/解析器本身然后是特定于语言的对象(字典、NSDictionary、Hashtable 等)用作内部表示。

【讨论】:

【参考方案3】:

实际上,如果键是 NaN 类型,浏览器不会更改顺序。

以下脚本将输出“一”、“二”、“三”:

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

【讨论】:

但这依赖于 JSON 的未定义行为。您与之交换的任何东西都可能具有不同的行为。 这个答案讨论了一个对象。该问题与json“列表”有关,只能推断为均值数组,该数组按json规范进行语义排序(请参阅Jeremy的回答)。【参考方案4】:

一些 JavaScript 引擎按插入顺序保存键。 V8,例如,keeps all keys in insertion order except for keys that can be parsed as unsigned 32-bit integers。

这意味着如果您运行以下任一命令:

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

在使用 V8 的 Chrome 上,您将始终按此顺序获得 dogbearmonkey。 Node.js 也使用 V8。即使您有数千个项目,这也是正确的。 YMMV 与其他 JavaScript 引擎。

演示here 和here。

【讨论】:

但这依赖于 JSON 的未定义行为。您与之交换的任何东西都可能具有不同的行为。 它可能适用于小物体。有一个对象实现将前三个键/值对存储在一个数组中,并在添加第四个条目时切换到哈希表是非常合理的。或者当您的最终用户比您测试过的项目多一件时。【参考方案5】:

“JSON 列表中元素的顺序是否保持不变?”不是一个好问题。您需要问“在执行 [...] 时是否保持 JSON 列表中元素的顺序?” 正如 Felix King 所指出的,JSON 是一种文本数据格式。它不会无缘无故地变异。不要将 JSON 字符串与 (JavaScript) 对象混淆。

您可能正在谈论像JSON.stringify(JSON.parse(...)) 这样的操作。现在的答案是:这取决于实施。 99%* 的 JSON 解析器不维护对象的顺序,并维护数组的顺序,但您不妨使用 JSON 来存储类似的东西


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

并使用维护对象顺序的解析器。

*可能更多:)

【讨论】:

错了,至少如果您谈论的是 JSON 解析器的使用。 V8 维护了这个顺序,我猜它单独占 JSON 解析器使用量的 1% 以上。 code.google.com/p/v8/issues/detail?id=164#c1 @BenAtkin 有趣的是,您的链接指向关于 V8 如何维持秩序的解释。 "事实上的标准是匹配插入顺序,V8 也这样做,但有一个例外" 所有人都是男性,但有一个例外:女性是女性。 @user123444555621 :D 声明:“所有人都是男性,但有一个例外:女性是女性”涵盖了所有可能的情况,但有一个例外:人类不能可以明确归类为两者之一或两者皆无。

以上是关于JSON 列表中元素的顺序是不是保留?的主要内容,如果未能解决你的问题,请参考以下文章

在 Python 中,从列表中删除重复项以使所有元素都是唯一的*同时保留顺序*的最快算法是啥? [复制]

Linq to Objects:GroupBy 是不是保留元素的顺序?

使用Python的设置差异时保留顺序

第三章 列表简介(二)

插入 SQL 时保留 JSON 数据的顺序

json_encode 不保留顺序