用于快速查找和有序循环的Javascript数据结构?
Javascript中是否有一种数据结构或模式可以用于快速查找(按键,如关联数组)和有序循环 好的,现在我使用对象文字来存储数据,但我刚刚发现Chrome在循环属性名时没有保持顺序 在Javascript中有解决这个问题的通用方法吗用于快速查找和有序循环的Javascript数据结构?,javascript,loops,object-literal,Javascript,Loops,Object Literal,Javascript中是否有一种数据结构或模式可以用于快速查找(按键,如关联数组)和有序循环 好的,现在我使用对象文字来存储数据,但我刚刚发现Chrome在循环属性名时没有保持顺序 在Javascript中有解决这个问题的通用方法吗 谢谢您的提示。自己创建一个数据结构。将排序存储在结构内部的数组中。将键映射的对象存储在常规对象中。让我们称之为OrderedMap,它将有一个映射、一个数组和四个基本方法 OrderedMap map _array set(key, val
谢谢您的提示。自己创建一个数据结构。将排序存储在结构内部的数组中。将键映射的对象存储在常规对象中。让我们称之为
OrderedMap
,它将有一个映射、一个数组和四个基本方法
OrderedMap
map
_array
set(key, value)
get(key)
remove(key)
forEach(fn)
function OrderedMap() {
this.map = {};
this._array = [];
}
插入元素时,将其添加到所需位置的数组以及对象中。按索引插入或在末尾插入为O(1)
删除对象时,请将其从数组和对象中删除。如果按键或值删除,则复杂度为O(n),因为需要遍历维持顺序的内部数组。按索引删除时,复杂性为O(1),因为您可以直接访问数组和对象中的值
OrderedMap.prototype.remove = function(key) {
var index = this._array.indexOf(key);
if(index == -1) {
throw new Error('key does not exist');
}
this._array.splice(index, 1);
delete this.map[key];
};
将在O(1)中进行查找。从关联数组(对象)中按键检索值
遍历将按顺序进行,并且可以使用这两种方法中的任何一种。当需要有序遍历时,创建一个包含对象(仅值)的数组并返回它。作为一个数组,它不支持键控访问。另一个选项是要求客户端提供一个回调函数,该函数应应用于数组中的每个对象
OrderedMap.prototype.forEach = function(f) {
var key, value;
for(var i = 0; i < this._array.length; i++) {
key = this._array[i];
value = this.map[key];
f(key, value);
}
};
OrderedMap.prototype.forEach=函数(f){
var键,值;
对于(var i=0;i
有关此类的文档和源代码,请参见Google在闭包库中实现的一个类。Chrome不维护对象文本中键顺序的唯一实例似乎是键是否为数字
var properties = ["damsonplum", "9", "banana", "1", "apple", "cherry", "342"];
var objLiteral = {
damsonplum: new Date(),
"9": "nine",
banana: [1,2,3],
"1": "one",
apple: /.*/,
cherry: {a: 3, b: true},
"342": "three hundred forty-two"
}
function load() {
var literalKeyOrder = [];
for (var key in objLiteral) {
literalKeyOrder.push(key);
}
var incremental = {};
for (var i = 0, prop; prop = properties[i]; i++) {
incremental[prop] = objLiteral[prop];
}
var incrementalKeyOrder = [];
for (var key in incremental) {
incrementalKeyOrder.push(key);
}
alert("Expected order: " + properties.join() +
"\nKey order (literal): " + literalKeyOrder.join() +
"\nKey order (incremental): " + incrementalKeyOrder.join());
}
在铬合金中,上述产品为:“19342,丹森李子,香蕉,苹果,樱桃”
在其他浏览器中,它生成“damsonplum、9、香蕉、1、苹果、樱桃、342”
所以,除非你的钥匙是数字的,否则我认为即使在Chrome中,你也是安全的。如果您的键是数字键,可能只需在它们前面加一个字符串。
,如果您的键是数字键
您可以在它们前面加上字符串以保持顺序
var qy = {
_141: '256k AAC',
_22: '720p H.264 192k AAC',
_84: '720p 3D 192k AAC',
_140: '128k AAC'
};
这通常适用于V8,因此也适用于Node.js吗?如何查找O(1)?如果您使用的不是数组索引,那么JS属性解析为O(n)(它必须通过原型链循环进行解析)请参阅属性查找,因为它必须向上遍历原型链,这一事实仍然不能使其为O(n)。设想一个4层的原型链层次结构,每层维护一个散列结构来保存键和值。那么它平均只需要4次这样的O(1)查找。这仍然是O(1)。现在,据我所知,ECMAScript并不强制要求实现细节,所以如果有人愿意,可以用O(n²)来实现。换句话说,它依赖于实现,但如果实现得最合理,那么平均可以预期有O(1)个查找。“O(1)描述了一种算法,该算法将始终在同一时间(或空间)内执行,而不管输入数据集的大小。”即hashmap查找,它不会根据hashmap的大小而改变。此查找将始终根据链中属性和原型的数量进行更改。这就是O(n)。它仍然以线性方式进行,但查找永远不会是O(1)。您正在讨论两个变量。第一个是散列映射中的项数,第二个是原型链的深度。原型链的深度(在这个特定场景中)是一个常数,并且不会随着散列映射中的项目数的增加而增加。有鉴于此,请重新阅读我之前的声明,现在对你们来说一切都是有意义的。如果不是,请检查这个。@ginman这不是O(n);O适用于您正在查找的项目数。添加一个常量(原型链)不会改变这一点,而您自己的引号“[…]不管输入数据集的位置如何”也说明了同样的事情。注意,JavaScript现在有一个本机
Map
,它有顺序循环。
var properties = ["damsonplum", "9", "banana", "1", "apple", "cherry", "342"];
var objLiteral = {
damsonplum: new Date(),
"9": "nine",
banana: [1,2,3],
"1": "one",
apple: /.*/,
cherry: {a: 3, b: true},
"342": "three hundred forty-two"
}
function load() {
var literalKeyOrder = [];
for (var key in objLiteral) {
literalKeyOrder.push(key);
}
var incremental = {};
for (var i = 0, prop; prop = properties[i]; i++) {
incremental[prop] = objLiteral[prop];
}
var incrementalKeyOrder = [];
for (var key in incremental) {
incrementalKeyOrder.push(key);
}
alert("Expected order: " + properties.join() +
"\nKey order (literal): " + literalKeyOrder.join() +
"\nKey order (incremental): " + incrementalKeyOrder.join());
}
var qy = {
_141: '256k AAC',
_22: '720p H.264 192k AAC',
_84: '720p 3D 192k AAC',
_140: '128k AAC'
};