'use strict'; /** * Computes a hash of an 'obj'. * Hash of a: * string is string * number is number as string * object is either result of calling $$hashKey function on the object or uniquely generated id, * that is also assigned to the $$hashKey property of the object. * * @param obj * @returns {string} hash string such that the same input will have the same hash string. * The resulting string key is in 'type:hashKey' format. */ function hashKey(obj, nextUidFn) { var key = obj && obj.$$hashKey; if (key) { if (typeof key === 'function') { key = obj.$$hashKey(); } return key; } var objType = typeof obj; if (objType == 'function' || (objType == 'object' && obj !== null)) { key = obj.$$hashKey = objType + ':' + (nextUidFn || nextUid)(); } else { key = objType + ':' + obj; } return key; } /** * HashMap which can use objects as keys */ function HashMap(array, isolatedUid) { if (isolatedUid) { var uid = 0; this.nextUid = function() { return ++uid; }; } forEach(array, this.put, this); } HashMap.prototype = { /** * Store key value pair * @param key key to store can be any type * @param value value to store can be any type */ put: function(key, value) { this[hashKey(key, this.nextUid)] = value; }, /** * @param key * @returns {Object} the value for the key */ get: function(key) { return this[hashKey(key, this.nextUid)]; }, /** * Remove the key/value pair * @param key */ remove: function(key) { var value = this[key = hashKey(key, this.nextUid)]; delete this[key]; return value; } };