Object property-names in JavaScript must be strings. This may seem obvious, but it has serious repercussions if you’re used to the free-wheeling style of Ruby’s Hash.
a = {}; b = {}; a[b] = null; console.log(typeof(b)); for (var i in a) { console.log(typeof(i)); }
In order to have the flexibility I’m used to, I whipped up this simple Hash that stores both keys and values in separate arrays.
/* JavaScript Associative Array */ function Hash(obj) { this.initialize(obj); } Hash.prototype = { initialize: function(obj) { this._keys = []; this._values = []; if (obj) for (var k in obj) { this.set(k, obj[k]); } }, set: function(key, value) { var i = this._indexOf(key); if (undefined == i) { this._keys.push(key); this._values.push(value); } else { this._values[i] = value; } return value; }, get: function(key) { return this._values[this._indexOf(key)]; }, remove: function(key) { var i = this._indexOf(key); if (undefined == i) return; var s = this._keys.length - 1; this._keys[i] = this._keys[s]; this._values[i] = this._values[s]; this._keys.pop(); this._values.pop(); }, hasKey: function(key) { return (undefined != this._indexOf(key)); }, keys: function() { return this._keys.slice(0, this._keys.length); }, values: function() { return this._values.slice(0, this._values.length); }, eachPair: function(func) { for (var i = this._keys.length - 1; i >= 0; i--) { func(this._keys[i], this._values[i]); } }, _indexOf: function(key) { for (var i = this._keys.length - 1; i >= 0; i--) { if (this._isElementSame(key, this._keys[i])) return i; } return undefined; }, _isElementSame: function(ele1, ele2) { if (ele1 == ele2) return true; if ('string' == typeof(ele1)) return false; if (ele1.hasOwnProperty('length')) { for (var i = ele1.length - 1; i >= 0; i--) { if (!this._isElementSame(ele1[i], ele2[i])) return false; } } // TODO: Need to do something smarter for objects return true; } }
Leave a Comment