一尘不染

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

javascript

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

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

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

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

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

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


阅读 277

收藏
2020-05-01

共1个答案

一尘不染

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

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];
});
2020-05-01