minis-data-old/node_modules/hashmap/hashmap.js
2024-08-06 22:13:11 +02:00

211 lines
4.6 KiB
JavaScript

/**
* HashMap - HashMap Class for JavaScript
* @author Ariel Flesler <aflesler@gmail.com>
* @version 2.0.6
* Homepage: https://github.com/flesler/hashmap
*/
(function(factory) {
/* global define */
if (typeof define === 'function' && define.amd) {
// AMD. Register as an anonymous module.
define([], factory);
} else if (typeof module === 'object') {
// Node js environment
var HashMap = module.exports = factory();
// Keep it backwards compatible
HashMap.HashMap = HashMap;
} else {
// Browser globals (this is window)
this.HashMap = factory();
}
}(function() {
function HashMap(other) {
this.clear();
switch (arguments.length) {
case 0: break;
case 1: {
if ('length' in other) {
// Flatten 2D array to alternating key-value array
multi(this, Array.prototype.concat.apply([], other));
} else { // Assumed to be a HashMap instance
this.copy(other);
}
break;
}
default: multi(this, arguments); break;
}
}
var proto = HashMap.prototype = {
constructor:HashMap,
get:function(key) {
var data = this._data[this.hash(key)];
return data && data[1];
},
set:function(key, value) {
// Store original key as well (for iteration)
var hash = this.hash(key);
if ( !(hash in this._data) ) {
this.size++;
}
this._data[hash] = [key, value];
},
multi:function() {
multi(this, arguments);
},
copy:function(other) {
for (var hash in other._data) {
if ( !(hash in this._data) ) {
this.size++;
}
this._data[hash] = other._data[hash];
}
},
has:function(key) {
return this.hash(key) in this._data;
},
search:function(value) {
for (var key in this._data) {
if (this._data[key][1] === value) {
return this._data[key][0];
}
}
return null;
},
delete:function(key) {
var hash = this.hash(key);
if ( hash in this._data ) {
this.size--;
delete this._data[hash];
}
},
type:function(key) {
var str = Object.prototype.toString.call(key);
var type = str.slice(8, -1).toLowerCase();
// Some browsers yield DOMWindow or Window for null and undefined, works fine on Node
if (!key && (type === 'domwindow' || type === 'window')) {
return key + '';
}
return type;
},
keys:function() {
var keys = [];
this.forEach(function(_, key) { keys.push(key); });
return keys;
},
values:function() {
var values = [];
this.forEach(function(value) { values.push(value); });
return values;
},
entries:function() {
var entries = [];
this.forEach(function(value, key) { entries.push([key, value]); });
return entries;
},
// TODO: This is deprecated and will be deleted in a future version
count:function() {
return this.size;
},
clear:function() {
// TODO: Would Object.create(null) make any difference
this._data = {};
this.size = 0;
},
clone:function() {
return new HashMap(this);
},
hash:function(key) {
switch (this.type(key)) {
case 'undefined':
case 'null':
case 'boolean':
case 'number':
case 'regexp':
return key + '';
case 'date':
return '♣' + key.getTime();
case 'string':
return '♠' + key;
case 'array':
var hashes = [];
for (var i = 0; i < key.length; i++) {
hashes[i] = this.hash(key[i]);
}
return '♥' + hashes.join('⁞');
default:
// TODO: Don't use expandos when Object.defineProperty is not available?
if (!key.hasOwnProperty('_hmuid_')) {
key._hmuid_ = ++HashMap.uid;
hide(key, '_hmuid_');
}
return '♦' + key._hmuid_;
}
},
forEach:function(func, ctx) {
for (var key in this._data) {
var data = this._data[key];
func.call(ctx || this, data[1], data[0]);
}
}
};
HashMap.uid = 0;
//- Add chaining to all methods that don't return something
['set','multi','copy','delete','clear','forEach'].forEach(function(method) {
var fn = proto[method];
proto[method] = function() {
fn.apply(this, arguments);
return this;
};
});
//- Backwards compatibility
// TODO: remove() is deprecated and will be deleted in a future version
HashMap.prototype.remove = HashMap.prototype.delete;
//- Utils
function multi(map, args) {
for (var i = 0; i < args.length; i += 2) {
map.set(args[i], args[i+1]);
}
}
function hide(obj, prop) {
// Make non iterable if supported
if (Object.defineProperty) {
Object.defineProperty(obj, prop, {enumerable:false});
}
}
return HashMap;
}));