如何在保持键查找的同时保持Javascript对象/数组的顺序?

时间:2011-04-24 23:32:10

标签: javascript data-structures

我有一些数据,我最初存储在一个通用的Javascript对象中,ID作为键:

{
  "7": {"id":"7","name":"Hello"},
  "3": {"id":"3","name":"World"},
  ...
}

但是,我发现浏览器在循环浏览时并不保证特定的对象顺序,因此在上面的“3”将出现在“7”之前。我改用这样的数组格式:

[
  {"id":"7","name":"Hello"},
  {"id":"3","name":"World"},
  ...
]

现在,我可以以正确的顺序循环但不能进行快速查找,例如data["3"],无需遍历数组。

有两种方法结合使用的好方法吗?我宁愿避免为每种格式使用单独的对象,因为对象非常大(数百个元素)。

2 个答案:

答案 0 :(得分:68)

我也遇到过这个问题。解决方案是除原始对象外还保留有序的键数组。

var objects = {
  "7": {"id":"7","name":"Hello"},
  "3": {"id":"3","name":"World"},
  ...
}
var order = [ "3", "7", ... ];

现在,如果你想要第二个元素,你可以进行这个查找:

var second_object = objects[order[1]];

ECMA标准没有说明对象中元素的顺序。特别是Chrome在看起来像数字时重新排序密钥。 例如:

var example = {
    "a": "a",
    "b": "b",
    "1": "1",
    "2": "2"
};

如果您在Chrome中打印,则会显示如下内容:

{
    1: "1",
    2: "2",
    "a": "a",
    "b": "b"
};

有点酸......但生活。

您也可以使用解决方案Andy链接,基本上将这两个包装在一个对象中。

我经常使用的另一种选择是自定义地图功能,它允许您指定遍历对象的顺序。通常,当您将数据打印到用户时,您将进行排序,因此当您循环并创建表行(例如)时,迭代器将按您的排序函数指定的顺序传递行。我认为这是个好主意:))

签名如下:

function map(object, callback, sort_function);

使用示例:

map(object, function (row) {
   table.add_row(row.header, row.value);
}, function (key1, key2) {
   return object[key1] - object[key2];
});

答案 1 :(得分:1)

有一些现成的库可用于提供“按提供”的 JSON 解析或“一致排序”的 JSON 打印以供显示,而不是自己编写代码。

您可能会考虑以下任何一个: