有没有一个用于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}'

也就是说,由于任何plain对象的toString()是[object Object],所以它们都处于相同的值.

我想创建一个hashmap,其中具有相同属性和值的对象具有相同的值,但是具有不同属性或值的对象会处理不同的值.那是:

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

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

var hash = {};
var b = {bar: 2,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?

更新:

相当的是,是否有一个很好的散列函数,使得:

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

解决方法

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

我几乎没有测试过,我确信会有一些不能处理的角落.

性能将会非常低效,因为__createHash函数需要遍历任何对象的成员,然后对它们进行排序,以便生成满足您的需求的“哈希”.

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 = {};
}

相关文章

前言 做过web项目开发的人对layer弹层组件肯定不陌生,作为l...
前言 前端表单校验是过滤无效数据、假数据、有毒数据的第一步...
前言 图片上传是web项目常见的需求,我基于之前的博客的代码...
前言 导出Excel文件这个功能,通常都是在后端实现返回前端一...
前言 众所周知,js是单线程的,从上往下,从左往右依次执行,...
前言 项目开发中,我们可能会碰到这样的需求:select标签,禁...