3 This file is part of Ext JS 4
5 Copyright (c) 2011 Sencha Inc
7 Contact: http://www.sencha.com/contact
9 GNU General Public License Usage
10 This file may be used under the terms of the GNU General Public License version 3.0 as published by the Free Software Foundation and appearing in the file LICENSE included in the packaging of this file. Please review the following information to ensure the GNU General Public License version 3.0 requirements will be met: http://www.gnu.org/copyleft/gpl.html.
12 If you are unsure which license is appropriate for your use, please contact the sales department at http://www.sencha.com/contact.
16 * @class Ext.util.HashMap
18 * Represents a collection of a set of key and value pairs. Each key in the HashMap
19 * must be unique, the same key cannot exist twice. Access to items is provided via
20 * the key only. Sample usage:
22 var map = new Ext.util.HashMap();
27 map.each(function(key, value, length){
28 console.log(key, value, length);
33 * <p>The HashMap is an unordered class,
34 * there is no guarantee when iterating over the items that they will be in any particular
35 * order. If this is required, then use a {@link Ext.util.MixedCollection}.
38 Ext.define('Ext.util.HashMap', {
40 observable: 'Ext.util.Observable'
44 * @cfg {Function} keyFn A function that is used to retrieve a default key for a passed object.
45 * A default is provided that returns the <b>id</b> property on the object. This function is only used
46 * if the add method is called with a single argument.
50 * Creates new HashMap.
51 * @param {Object} config (optional) Config object.
53 constructor: function(config) {
54 config = config || {};
62 * Fires when a new item is added to the hash
63 * @param {Ext.util.HashMap} this.
64 * @param {String} key The key of the added item.
65 * @param {Object} value The value of the added item.
70 * Fires when the hash is cleared.
71 * @param {Ext.util.HashMap} this.
76 * Fires when an item is removed from the hash.
77 * @param {Ext.util.HashMap} this.
78 * @param {String} key The key of the removed item.
79 * @param {Object} value The value of the removed item.
84 * Fires when an item is replaced in the hash.
85 * @param {Ext.util.HashMap} this.
86 * @param {String} key The key of the replaced item.
87 * @param {Object} value The new value for the item.
88 * @param {Object} old The old value for the item.
93 me.mixins.observable.constructor.call(me, config);
102 * Gets the number of items in the hash.
103 * @return {Number} The number of items in the hash.
105 getCount: function() {
110 * Implementation for being able to extract the key from an object if only
111 * a single argument is passed.
113 * @param {String} key The key
114 * @param {Object} value The value
115 * @return {Array} [key, value]
117 getData: function(key, value) {
118 // if we have no value, it means we need to get the key from the object
119 if (value === undefined) {
121 key = this.getKey(value);
128 * Extracts the key from an object. This is a default implementation, it may be overridden
129 * @param {Object} o The object to get the key from
130 * @return {String} The key to use.
132 getKey: function(o) {
137 * Adds an item to the collection. Fires the {@link #add} event when complete.
138 * @param {String} key <p>The key to associate with the item, or the new item.</p>
139 * <p>If a {@link #getKey} implementation was specified for this HashMap,
140 * or if the key of the stored items is in a property called <tt><b>id</b></tt>,
141 * the HashMap will be able to <i>derive</i> the key for the new item.
142 * In this case just pass the new item in this parameter.</p>
143 * @param {Object} o The item to add.
144 * @return {Object} The item added.
146 add: function(key, value) {
150 if (arguments.length === 1) {
152 key = me.getKey(value);
155 if (me.containsKey(key)) {
156 return me.replace(key, value);
159 data = me.getData(key, value);
164 me.fireEvent('add', me, key, value);
169 * Replaces an item in the hash. If the key doesn't exist, the
170 * {@link #add} method will be used.
171 * @param {String} key The key of the item.
172 * @param {Object} value The new value for the item.
173 * @return {Object} The new value of the item.
175 replace: function(key, value) {
180 if (!me.containsKey(key)) {
185 me.fireEvent('replace', me, key, value, old);
190 * Remove an item from the hash.
191 * @param {Object} o The value of the item to remove.
192 * @return {Boolean} True if the item was successfully removed.
194 remove: function(o) {
195 var key = this.findKey(o);
196 if (key !== undefined) {
197 return this.removeAtKey(key);
203 * Remove an item from the hash.
204 * @param {String} key The key to remove.
205 * @return {Boolean} True if the item was successfully removed.
207 removeAtKey: function(key) {
211 if (me.containsKey(key)) {
215 me.fireEvent('remove', me, key, value);
222 * Retrieves an item with a particular key.
223 * @param {String} key The key to lookup.
224 * @return {Object} The value at that key. If it doesn't exist, <tt>undefined</tt> is returned.
227 return this.map[key];
231 * Removes all items from the hash.
232 * @return {Ext.util.HashMap} this
234 clear: function(/* private */ initial) {
238 if (initial !== true) {
239 me.fireEvent('clear', me);
245 * Checks whether a key exists in the hash.
246 * @param {String} key The key to check for.
247 * @return {Boolean} True if they key exists in the hash.
249 containsKey: function(key) {
250 return this.map[key] !== undefined;
254 * Checks whether a value exists in the hash.
255 * @param {Object} value The value to check for.
256 * @return {Boolean} True if the value exists in the dictionary.
258 contains: function(value) {
259 return this.containsKey(this.findKey(value));
263 * Return all of the keys in the hash.
264 * @return {Array} An array of keys.
266 getKeys: function() {
267 return this.getArray(true);
271 * Return all of the values in the hash.
272 * @return {Array} An array of values.
274 getValues: function() {
275 return this.getArray(false);
279 * Gets either the keys/values in an array from the hash.
281 * @param {Boolean} isKey True to extract the keys, otherwise, the value
282 * @return {Array} An array of either keys/values from the hash.
284 getArray: function(isKey) {
289 if (map.hasOwnProperty(key)) {
290 arr.push(isKey ? key: map[key]);
297 * Executes the specified function once for each item in the hash.
298 * Returning false from the function will cease iteration.
300 * The paramaters passed to the function are:
301 * <div class="mdetail-params"><ul>
302 * <li><b>key</b> : String<p class="sub-desc">The key of the item</p></li>
303 * <li><b>value</b> : Number<p class="sub-desc">The value of the item</p></li>
304 * <li><b>length</b> : Number<p class="sub-desc">The total number of items in the hash</p></li>
306 * @param {Function} fn The function to execute.
307 * @param {Object} scope The scope to execute in. Defaults to <tt>this</tt>.
308 * @return {Ext.util.HashMap} this
310 each: function(fn, scope) {
311 // copy items so they may be removed during iteration.
312 var items = Ext.apply({}, this.map),
314 length = this.length;
316 scope = scope || this;
318 if (items.hasOwnProperty(key)) {
319 if (fn.call(scope, key, items[key], length) === false) {
328 * Performs a shallow copy on this hash.
329 * @return {Ext.util.HashMap} The new hash object.
332 var hash = new this.self(),
336 hash.suspendEvents();
338 if (map.hasOwnProperty(key)) {
339 hash.add(key, map[key]);
348 * Find the key for a value.
349 * @param {Object} value The value to find.
350 * @return {Object} The value of the item. Returns <tt>undefined</tt> if not found.
352 findKey: function(value) {
357 if (map.hasOwnProperty(key) && map[key] === value) {