2013-02-01 90 views
4

我的任务有序映射实现

在我的JavaScript代码,我经常使用对象的“地图”键的值,所以我可以在以后通过一定的值直接访问它们。例如:

var helloMap = {}; 
helloMap.de = "Hallo"; 
helloMap["en"] = "Hello"; 
helloMap.es = "Hola"; 

所以我建立通过一步在我的源代码使用两个可用符号对象样式阵列样式地图对象的步骤。

后来我可以访问我通过helloMap["de"]添加的值。因此,如果我不必关心在对象上设置属性的顺序,那就好了。

如果我想现在迭代对象的属性,据我所知,没有办法确保我将按照它们添加的顺序迭代它们。

注:我不能使用一些包装对象,只是在那里举行一个数组,然后使用它的方法来添加值,所以是这样的:

var HelloMap = function(){ 
    this.myMap = []; 
    this.addProperty = function(key, value){ 
    this.myMap.push({key: key, value: value}); 
    } 
} 

或类似的东西不会为我工作。所以对于使用该对象的程序员来说,解决方案必须是绝对透明的。

这就是说我需要的对象将是一个空对象,它维护添加到它的属性的顺序。像这样的东西会做:

var helloMap = {}; 
helloMap = getOrderAwareObject(helloMap); 

,这样的形式helloMap.xy = "foo"helloMap["yz"] = "bar"将在对象跟踪“以”每进一步分配,

可能的解决方案

因为我做在下划线或jQuery中找不到任何解决方案给我这样一个特殊的对象,我碰到了为JavaScript对象中的属性定义getter和setter的可能性,因为我可以依靠ECMAScript 5标准我可以使用它。

这个问题是,你必须知道在对象被设置之前可以设置的所有可能的属性。因为如果你定义它你得到名称它。

我所寻找的东西就像一个默认吸气默认二传手其适用的对象,如果没有getter和setter已为属性定义。所以我可以隐藏排序的地图后面的对象界面。

  • 在你知道的任何框架中,是否已经有解决方案?
  • 有没有类似“default getter/setter”的机制?
+0

如果顺序很重要,那么你必须使用一个数组。 –

+0

是的..好..谢谢。但关联数组的问题在于,它们不能通过我需要的点运算符来访问。顺便说一下......你确定他们甚至保持了他们的订单吗? – Chris

+1

Javascript不会执行关联数组。您可以设置数组属性,但它们独立于索引数组项,并且与无格式js对象的属性相同。 –

回答

6

恐怕你需要一个使用数组的内部封装器。 ECMAScript 5(这是当前浏览器JavaScript实现所基于的标准)根本不允许有序的对象属性。

但是,ECMAScript 6将有一个Map implementation具有有序的属性。另见http://www.nczonline.net/blog/2012/10/09/ecmascript-6-collections-part-2-maps/

ECMAScript中6

还可能有其他的选择,请参阅以下问题:

How can I define a default getter and setter using ECMAScript 5?

+0

无法预先添加到ES6 Map类型的权利? –

3

我不知道一个通​​用的解决方案,但非一般的解决方案是非常简单的构造。

通常,您维护一个对象数组,其中包含几个定义为数组属性的方法。至少,这是我的方法。

下面是从一个更大的应用为例,采取(以修饰的形式):

var srcs = []; 
srcs.find = function(dist) { 
    var i; 
    for(i=0; i<this.length; i++) { 
     if(dist <= this[i].dist) { return this[i]; } 
    } 
    return null; 
}; 
srcs.add = function(dist, src) { 
    this.push({ dist:dist, src:src }); 
} 
srcs.remove = function(dist) { 
    var i; 
    for(i=0; i<this.length; i++) { 
     if(this[i].dist === dist) { 
      srcs.splice(i,1); 
      return true; 
     } 
    } 
    return false; 
}; 
srcs.add(-1, 'item_0.gif'); 
srcs.add(1.7, 'item_1.gif'); 
srcs.add(5, 'item_2.gif'); 
srcs.add(15, 'item_3.gif'); 
srcs.add(90, 'item_4.gif'); 

不幸的是,你失去了一个简单的JS对象查找的简单,但是这是你付出的代价为具有有序实体。

如果你绝对必须有秩序和dot.notation,然后维持一个普通JS对象查找订单的数组。小心谨慎,这两者可以保持完整的完整性。

+1

感谢您的最后提示!同时维护一个对象和一个数组对我的具体情况来说似乎是一个很好的“现在”解决方案。 – Chris

4

添加链接到自定义JavaScript库,该库提供Sorted地图和其他实现,以供将来在此主题中参考。退房https://github.com/monmohan/dsjslib -msingh

+0

这看起来很有用。感谢发布。我也发现了这个(http://www.collectionsjs.com/sorted-map),但文档不清楚,API令人困惑(例如set(key,value)vs add(value,key))和as结果,我很难相信实现 – i8abug

0

看到我对this问题的回答。我实现了一个基本的有序哈希表(ES 5+只,没有刻意去填充工具)

-1
var put = function(k,v){ 
if(map[k]){ 
    console.log("Key "+ k+" is already present"); 
}else 
{ 
    var newMap = {}; 
    map[k] = v; 
    Object.keys(map).sort().forEach(function(key){ 
    newMap[key] = map[key]; 
}); 
    map = newMap; 
    //delete newMap; in case object memory need to release 
    return map; 
} 
} 

Put方法将总是一个键值对,在内部创建另一个地图与实际地图,更新排序键该值并返回带有排序键的更新地图。无需外部库包含。

+0

堆栈溢出是一个很好的做法,为解决方案的工作原理添加一个解释。有关更多信息,请阅读[如何回答](// stackoverflow.com/help/how-to-answer)。 –