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

IT技术 javascript data-structures
2021-02-08 02:16:32

我有一些最初存储在通用 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个回答

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

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];
});
好主意,谢谢!我实际上做了与您建议的相反的操作,并将主数据存储保留为一个数组(为了更好的循环),然后我将数组索引存储在一个对象中,该对象是动态生成的。
2021-03-17 02:16:32
使用正常的 for(var i; i<lenght; i++) 循环简单地将值分配给索引不是更容易吗?
2021-03-22 02:16:32

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

您可能会考虑以下任一项: