Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
227 changes: 227 additions & 0 deletions HashMap2.4.0/hashmap.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,227 @@
/**
* HashMap - HashMap Class for JavaScript
* @author Ariel Flesler <aflesler@gmail.com>
* @version 2.4.0
* Homepage: https://github.com/flesler/hashmap
*/

(function(factory) {
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;

// Iterator protocol for ES6
if (typeof Symbol !== 'undefined' && typeof Symbol.iterator !== 'undefined') {
proto[Symbol.iterator] = function() {
var entries = this.entries();
var i = 0;
return {
next:function() {
if (i === entries.length) { return { done: true }; }
var currentEntry = entries[i++];
return {
value: { key: currentEntry[0], value: currentEntry[1] },
done: false
};
}
};
};
}

//- 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;
}));
1 change: 1 addition & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
(The MIT License)

Copyright (c) 2012 Ariel Flesler <aflesler@gmail.com>
Copyright (c) 2021 Jack Moxley https://github.com/jackmoxley

Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
Expand Down
Loading