2011-04-24 87 views
45

我有我本来存储在一个通用的Javascript对象,与ID为关键字的一些数据:如何保持一个JavaScript对象/数组的排序,同时还保持密钥查找?

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

然而,我发现,浏览器不能保证通过它们循环的时候,所以在特定对象顺序上述“3”会在“7”之前出现。我切换到使用一个这样的数组格式:

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

现在,我可以按照正确的顺序循环,但不能做快速查找,例如不需要遍历数组。

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

+5

可能重复[吗?快速查找的Javascript数据结构和有序循环( http://stackoverflow.com/questions/3549894/javascript-data-structure-for-fast-lookup-and-ordered-looping) – 2011-04-24 23:34:41

+0

不知道有一个更好的方式来实现这个比我已经链接到的答案。它打破了你为每个目标避免单独物体的目标 - 但我很想知道更好的方法! :) – 2011-04-24 23:36:08

回答

61

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

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]; 
}); 
+0

好主意,谢谢!我实际上做了与你建议的相反的操作,并将主数据存储保存为一个数组(为了更好的循环),然后将数组索引存储在一个对象中,并在运行时生成。 – DisgruntledGoat 2011-04-26 22:36:46

+0

如果简单地将值分配给(var i; i MJB 2012-10-18 08:19:09

相关问题