有没有JavaScript的hashmap库? [英] Is there a hashmap library for JavaScript?

查看:84
本文介绍了有没有JavaScript的hashmap库?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在JavaScript中,所有对象都像hashmaps一样。但是,这些hashmaps的关键必须是字符串。如果他们不是,他们转换为 toString()。这意味着:

  var a = {foo:1}; 
var b = {bar:2};
var o = {};
o [a] = 100;
o [b]; // 100
JSON.stringify(o); //'{[object Object]:100}'

也就是说,任何普通对象的c $ c> toString()都是 [object Object] ,它们都是地址相同的值。
$ b

我想创建一个散列图,其中具有相同属性和值的对象具有相同的值,但具有不同属性或值的对象具有不同的值。即:

  var a = {foo:1}; 
var b = {bar:2,baz:3};
var c = {baz:3,bar:2};
var hash = new Hash();
hash.set(a,100);
hash.get(b); //未定义
hash.set(b,200);
hash.get(b); // 200
hash.get(c); // 200

我的第一个直觉是使用 JSON.stringify()将对象转换为字符串,但是:

  var hash = {}; 
var b = {bar:2,baz:3};
var c = {baz:3,bar:2};
hash [JSON.stringify(b)] = 100
hash [JSON.stringify(b)] // 100
hash [JSON.stringify(c)] // undefined
JSON.stringify(b)//'{bar:2,baz:3}'
JSON.stringify(c)//'{baz:3,bar:2} '

也就是说,JSON序列化依赖于顺序。



是否有一个好的库或技术来实现这样的hashmap?

更新

等价地,是否存在一个很好的散列函数:

$ $ p $ hash({foo:1, bar:2})== hash({bar:2,foo:1})


解决方案

这是一个快速的概念验证...



我几乎没有测试过它,我确信那里将是无法处理的角落案例。



由于 __ createHash 函数的性能会非常低效需要递归通过任何对象的成员,然后对它们进行排序,以便生成符合您要求的散列。

  HashMap = function(){
this。 get = function(key){
var hash = this .__ createHash(key);
返回这个.__ map [hash];
};

this.set = function(key,value){
var hash = this .__ createHash(key);
this .__ map [hash] = value;
};

this .__ createHash = function(key){
switch(typeof key){
case'function':
return'function';

'undefined':
return'undefined';

case'string':
return'''+ key.replace('''''''')+''';

case'对象':
if(!key){
return'null';
}

switch(Object.prototype.toString.apply(key)){
case'[object Array]':
var elements = [];
for(var i = 0; i elements.push( this .__ createHash(key [i]));
}
return'['+ elements.join(',')+']';

case'[object ()
返回'#'+ key.getUTCFullYear()。toString .toString()
+ key.getUTCHours()。toString()
+ key.getUTCMinutes()。toString()
+ key.getUTCSeconds()。toString()+'#';

默认值:
var members = [];
for(var m in key){
members.push(m +'='+ this .__ createHash(key [m]));
}
members.sort();
return'{'+ members.join(',')+'}';
}

默认值:
return key.toString();
}
};

this .__ map = {};
}


In JavaScript, all Objects act a bit like hashmaps. However, the keys to these hashmaps must be strings. If they're not, they're converted with toString(). That means:

var a = {foo: 1};
var b = {bar: 2};
var o = {};
o[a] = 100;
o[b];              // 100
JSON.stringify(o); // '{"[object Object]":100}'

That is, since the toString() of any plain Object is [object Object], they all address the same value.

I'd like to create a hashmap where Objects with the same properties and values address the same value, but objects with different properties or values address different values. That is:

var a = {foo: 1};
var b = {bar: 2, baz: 3};
var c = {baz: 3, bar: 2};
var hash = new Hash();
hash.set(a, 100);
hash.get(b);      // undefined
hash.set(b, 200);
hash.get(b);      // 200
hash.get(c);      // 200

My first instinct was to use JSON.stringify() to turn objects into strings, but:

var hash = {};
var b = {bar: 2, baz: 3};
var c = {baz: 3, bar: 2};
hash[JSON.stringify(b)] = 100
hash[JSON.stringify(b)] // 100
hash[JSON.stringify(c)] // undefined
JSON.stringify(b)       // '{"bar":2,"baz":3}'
JSON.stringify(c)       // '{"baz":3,"bar":2}'

That is, JSON serialization is order-dependent.

Is there a good library or technique to implement a hashmap like this?

Update:

Equivalently, is there a good hashing function such that:

hash({foo: 1, bar: 2}) == hash({bar: 2, foo: 1})

解决方案

Here's a quick proof-of-concept...

I've hardly tested it at all, and I'm certain that there will be corner-cases that it can't deal with.

Performance will be hideously inefficient because the __createHash function needs to recurse through the members of any objects and then sort them, in order to generate a "hash" that meets your requirements.

HashMap = function() {
    this.get = function(key) {
        var hash = this.__createHash(key);
        return this.__map[hash];
    };

    this.set = function(key, value) {
        var hash = this.__createHash(key);
        this.__map[hash] = value;
    };

    this.__createHash = function(key) {
        switch (typeof key) {
            case 'function':
                return 'function';

            case 'undefined':
                return 'undefined';

            case 'string':
                return '"' + key.replace('"', '""') + '"';

            case 'object':
                if (!key) {
                    return 'null';
                }

                switch (Object.prototype.toString.apply(key)) {
                    case '[object Array]':
                        var elements = [];
                        for (var i = 0; i < key.length; i++) {
                            elements.push(this.__createHash(key[i]));
                        }
                        return '[' + elements.join(',') + ']';

                    case '[object Date]':
                        return '#' + key.getUTCFullYear().toString()
                                   + (key.getUTCMonth() + 1).toString()
                                   + key.getUTCDate().toString()
                                   + key.getUTCHours().toString()
                                   + key.getUTCMinutes().toString()
                                   + key.getUTCSeconds().toString() + '#';

                    default:
                        var members = [];
                        for (var m in key) {
                            members.push(m + '=' + this.__createHash(key[m]));
                        }
                        members.sort();
                        return '{' + members.join(',') + '}';
                }

            default:
                return key.toString();
        }
    };

    this.__map = {};
}

这篇关于有没有JavaScript的hashmap库?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆