1 /** 2 * @author Gillis Haasnoot <gillis.haasnoot@gmail.com> 3 * @package Banana.Util 4 * @summary ArrayBiCollection 5 */ 6 7 goog.provide('Banana.Util.ArrayBiCollection'); 8 9 goog.require('Banana.Util.ArrayUniCollection'); 10 11 /** 12 * Array bi collection is a wrapper class holding two Banana.Util.ArrayUniCollection 13 * In one we keep track of key -> index. In the other key -> data. 14 * 15 * @constructor 16 */ 17 Banana.Util.ArrayBiCollection = function() 18 { 19 this.keyIndex = new Banana.Util.ArrayUniCollection(); 20 this.keyData = new Banana.Util.ArrayUniCollection(); 21 22 /** 23 * Clones the collection 24 * @return {Banana.Util.ArrayBiCollection} 25 */ 26 this.clone = function() 27 { 28 var t = new Banana.Util.ArrayBiCollection(); 29 t.keyIndex = this.keyIndex.clone(); 30 t.keyData = this.keyData.clone(); 31 return t; 32 } 33 34 /** 35 * gets indexed array with elements containing the data 36 * @return {Array} 37 */ 38 this.getArray = function() 39 { 40 var a = []; 41 42 this.each(function(i,d) 43 { 44 a.push(d); 45 }); 46 47 return a; 48 } 49 50 /** 51 * Adds new item to the collection. Key in string or int format. 52 * @param {String} key 53 * @param {mixed} item 54 */ 55 this.addItem = function(key, item) 56 { 57 this.remove(key); 58 this.keyIndex.addItem(key,this.keyIndex.getLength()) 59 this.keyData.addItem(key,item); 60 }; 61 62 /** 63 * Gets data by key 64 * @param {String} key 65 * @return {mixed} 66 */ 67 this.getItem = function(key) 68 { 69 return this.keyData.getItem(key); 70 }; 71 72 /** 73 * Gets item by index 74 * @param {int} index 75 * @return {mixed} 76 */ 77 this.getItemByIndex = function(index) 78 { 79 return this.keyData.getItemByIndex(index); 80 } 81 82 /** 83 * Gets key by index 84 * @param {int} index 85 * @return {String} 86 */ 87 this.getKeyByIndex = function(index) 88 { 89 return this.keyIndex.getKeyByIndex(index); 90 } 91 92 /** 93 * TODO: (Duplicated implementation of getItem??) 94 * Gets item by key 95 * @ignore 96 * @param {String} key 97 * @return {mixed} 98 */ 99 this.getItemByKey = function(key) 100 { 101 return this.getItemByIndex(this.getIndex(key)); 102 } 103 104 /** 105 * gets index by key 106 * @param {String} key 107 * @return {int} 108 */ 109 this.getIndex = function(key) 110 { 111 return this.keyIndex.getItem(key); 112 } 113 114 /** 115 * gets length of the collection 116 * @return {int} 117 */ 118 this.getLength = function() 119 { 120 return this.keyIndex.getLength(); 121 } 122 123 /** 124 * checks if given key exists in the collection 125 * @param {String} key 126 * @return {boolean} true if found 127 */ 128 this.isset = function(key) 129 { 130 return (this.getItem(key) != undefined); 131 } 132 133 /** 134 * Removes item by key 135 * @param {String} key 136 */ 137 this.remove = function(key) 138 { 139 if (this.isset(key)) 140 { 141 142 var index = this.keyIndex.getItem(key); 143 144 this.keyIndex.removeByIndex(index); 145 this.keyData.removeByIndex(index); 146 147 ///we need to decrement keyindex items after removed item 148 var len = this.getLength(); 149 for (var i = index; i < len; i++) 150 { 151 152 this.keyIndex.alterItem(this.getKeyByIndex(i),i); 153 154 } 155 } 156 } 157 158 /** 159 * clears the collection 160 */ 161 this.clear = function() 162 { 163 this.keyIndex = new Banana.Util.ArrayUniCollection(); 164 this.keyData = new Banana.Util.ArrayUniCollection(); 165 } 166 167 /** 168 * sorts the collection 169 * @param {Function} fn 170 */ 171 this.sort = function(fn) 172 { 173 var sortedKeys = this.keyIndex.sortedKeys(fn); 174 var oldData = this.keyData; 175 this.clear(); 176 177 for (var i = 0; i < sortedKeys.length; i++) 178 { 179 this.addItem(sortedKeys[i], oldData.getItem(sortedKeys[i])); 180 } 181 182 return this; 183 } 184 185 /** 186 * Walks over the collection 187 * @param {Function} f 188 * @param {mixed} userdata 189 */ 190 this.each = function(f,userdata) 191 { 192 var len = this.getLength(); 193 for (var i = 0; i < len; i++) 194 { 195 f(i,this.getItemByIndex(i),userdata); 196 } 197 } 198 }