/js/lib/SortedLookupTable.js
JavaScript | 200 lines | 78 code | 20 blank | 102 comment | 11 complexity | 97ff6611236f07be71506aca33db70ee MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.1, MPL-2.0-no-copyleft-exception, BSD-3-Clause
1/** 2File: 3 SortedLookupTable.js 4Created By: 5 (Class from http://blog.jcoglan.com/2010/10/18/i-am-a-fast-loop/) 6 Copy->Pasted->Modified by Mario Gonzalez 7 8Project : 9 Ogilvy Holiday Card 2010 10Abstract: 11 12 A sorted LookupTable is a data structure that provides us a way to iterate thru objects at a speed 13 comparable to reverse while, but also have named keys as we would if we used an object (which provides very slow iteration) 14 It also gives us O(log n) removal of objects. 15Basic Usage: 16 17 http://blog.jcoglan.com/2010/10/18/i-am-a-fast-loop/ 18*/ 19// @getify's solution 20//var Set = (function() 21//{ 22// var indexOf = Array.prototype.indexOf; 23// 24// if (typeof indexOf !== 'function') 25// { 26// indexOf = function(value) 27// { 28// for (var index = 0, length = this.length; index < length; index++) 29// { 30// if (this[index] === value) 31// { 32// return index; 33// } 34// } 35// return -1; 36// }; 37// } 38// 39// function Set() 40// { 41// this.set = []; 42// } 43// 44// Set.prototype = { 45// 'constructor': Set, 46// 'put': function(value, key) 47// { 48// var index = indexOf.call(this.set, key); 49// if (index !== -1 && index % 2 === 0) 50// { 51// this.set.splice(index, 2); 52// } 53// this.set.push(key, value); 54// }, 55// 'get': function(key) 56// { 57// var index = indexOf.call(this.set, key); 58// return (index !== -1 && index % 2 === 0) ? this.set[++index] : null; 59// }, 60// 'containsKey': function(key) 61// { 62// var index = indexOf.call(this.set, key); 63// return (index !== -1 && index % 2 === 0); 64// }, 65// 'containsValue': function(value) 66// { 67// var index = indexOf.call(this.set, value); 68// return (index !== -1 && index % 2 !== 0); 69// }, 70// 'remove': function(key) 71// { 72// var index = indexOf.call(this.set, key), 73// value = null; 74// if (index !== -1 && index % 2 === 0) 75// { 76// value = this.set.splice(index, 2)[1]; 77// } 78// return value; 79// }, 80// 81// 'forEach': function(block, context) 82// { 83// var set = this.set, 84// i = this.set.length-1, 85// key; 86// 87// while (i > 0) 88// { 89// block.call(context, set[i - 1], set[key]); 90// i-=2; 91// } 92// } 93// }; 94// 95// return Set; 96//}()); 97 98(function() { 99 /** 100 * LookupTable 101 */ 102 LookupTable = function() 103 { 104 this._keys = []; 105 this._data = {}; 106 this.nextUUID = 0; 107 }; 108 109 110 LookupTable.prototype.setObjectForKey = function(value, key) 111 { 112 if (!this._data.hasOwnProperty(key)) this._keys.push(key); 113 this._data[key] = value; 114 115 return value; 116 }; 117 118 LookupTable.prototype.objectForKey = function(key) 119 { 120 return this._data[key]; 121 }; 122 123 LookupTable.prototype.forEach = function(block, context) 124 { 125 var keys = this._keys, 126 data = this._data, 127 i = keys.length, 128 key; 129 130 while (i--) 131 { 132 key = keys[i]; 133 block.call(context, key, data[key]); 134 } 135 }; 136 137 LookupTable.prototype.count = function() 138 { 139 return this._keys.length; 140 }; 141 142 LookupTable.prototype.dealloc = function() 143 { 144 delete this._keys; 145 delete this._data; 146 }; 147 148 149 150 /** 151 * Sorted LookupTable, 152 */ 153 SortedLookupTable = function() 154 { 155 LookupTable.call(this); 156 }; 157 158 SortedLookupTable.prototype = new LookupTable(); 159 160 SortedLookupTable.prototype.setObjectForKey = function(value, key) 161 { 162 if( !this._data.hasOwnProperty( key ) ) 163 { 164 var index = this._indexOf(key); 165 this._keys.splice(index, 0, key); 166 } 167 this._data[key] = value; 168 169 return value; 170 }; 171 172 SortedLookupTable.prototype.remove = function(key) 173 { 174 if (!this._data.hasOwnProperty(key)) return; 175 delete this._data[key]; 176 var index = this._indexOf(key); 177 this._keys.splice(index, 1); 178 }; 179 180 SortedLookupTable.prototype._indexOf = function(key) 181 { 182 var keys = this._keys, 183 n = keys.length, 184 i = 0, 185 d = n; 186 187 if (n === 0) return 0; 188 if (key < keys[0]) return 0; 189 if (key > keys[n - 1]) return n; 190 191 while (key !== keys[i] && d > 0.5) { 192 d = d / 2; 193 i += (key > keys[i] ? 1: -1) * Math.round(d); 194 if (key > keys[i - 1] && key < keys[i]) d = 0; 195 } 196 return i; 197 }; 198 199 return SortedLookupTable; 200})();