jquery 有序Map的JavaScript实现

txu3uszq  于 2023-02-12  发布在  jQuery
关注(0)|答案(5)|浏览(183)

我的任务

在我的JavaScript代码中,我经常使用对象将键“Map”到值,这样我就可以通过某个值直接访问它们。

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

因此,我在源代码中使用两种可用的符号 object stylearray style 逐步构建map对象。
稍后我可以访问我通过helloMap["de"]添加的值,所以如果我不需要关心属性在对象上设置的顺序,这一切都很好。
如果我想现在就迭代对象属性,就我所知,没有办法确保我会按照它们被添加的顺序(插入顺序)迭代它们。

**注意:**我不能使用一些 Package 器对象,简单地在其中保存一个数组,然后使用它的方法来添加值,这样就像这样:

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"的每个进一步的赋值将在对象“in order”中被跟踪,

可能的解决方案

由于我没有在下划线或jQuery中找到任何解决方案,因此我遇到了使用Object.defineProperty为JavaScript对象中的属性定义getter和setter的可能性,因为我可以依赖 ECMAScript 5 标准,我可以使用它。
这个方法的问题是,你必须知道所有可以在对象上设置的属性,在它们被真正设置之前,因为如果你 * 定义 * 它,你就必须 * 命名 * 它。
我正在搜索的是类似于Default GetterDefault Setter的东西,如果没有为属性定义getter和setter,则应用于对象。因此,我可以将sorted map隐藏在对象接口后面。

  • 在你所知道的任何框架中,是否已经有了解决方案?
  • 是否有类似“默认getter/setter”的机制?
ljo96ir5

ljo96ir51#

恐怕您需要某种内部使用数组的 Package 器。ECMAScript5(当前浏览器JavaScript实现所基于的标准)根本不允许有序的对象属性。
但是,ECMAScript 6将有一个具有有序属性的Map实现。另请参见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?

biswetbf

biswetbf2#

添加一个链接到一个自定义的javascript库,它提供了SortedMap和其他实现,以供将来在本主题中参考。

3zwjbxry

3zwjbxry3#

我不知道一般的解决方案,但非一般的解决方案是非常简单的构造。
通常情况下,你维护一个对象的Array,并将几个方法定义为Array的属性,至少这是我的方法。
下面是一个例子,取自(以修改后的形式)一个更大的应用程序:

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对象查找的简单性,但这是您为拥有有序实体所付出的代价。
如果你一定要有order和.notation,那么就维护一个普通的js对象来查找 *,维护一个数组来排序 *。小心点,这两个对象可以保持完整。

xxb16uws

xxb16uws4#

请看我对this问题的回答。我实现了一个基本的有序哈希表(仅适用于ES5+,不需要polyfill)

3ks5zfa0

3ks5zfa05#

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方法将总是接受一个键-值对,在内部从实际Map创建另一个带有排序键的Map,更新值并返回带有排序键的更新Map。

相关问题