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', {
41 * @cfg {Function} keyFn A function that is used to retrieve a default key for a passed object.
42 * A default is provided that returns the <b>id</b> property on the object. This function is only used
43 * if the add method is called with a single argument.
47 observable: 'Ext.util.Observable'
51 * Creates new HashMap.
52 * @param {Object} config (optional) Config object.
54 constructor: function(config) {
55 config = config || {};
63 * Fires when a new item is added to the hash
64 * @param {Ext.util.HashMap} this.
65 * @param {String} key The key of the added item.
66 * @param {Object} value The value of the added item.
71 * Fires when the hash is cleared.
72 * @param {Ext.util.HashMap} this.
77 * Fires when an item is removed from the hash.
78 * @param {Ext.util.HashMap} this.
79 * @param {String} key The key of the removed item.
80 * @param {Object} value The value of the removed item.
85 * Fires when an item is replaced in the hash.
86 * @param {Ext.util.HashMap} this.
87 * @param {String} key The key of the replaced item.
88 * @param {Object} value The new value for the item.
89 * @param {Object} old The old value for the item.
94 me.mixins.observable.constructor.call(me, config);
103 * Gets the number of items in the hash.
104 * @return {Number} The number of items in the hash.
106 getCount: function() {
111 * Implementation for being able to extract the key from an object if only
112 * a single argument is passed.
114 * @param {String} key The key
115 * @param {Object} value The value
116 * @return {Array} [key, value]
118 getData: function(key, value) {
119 // if we have no value, it means we need to get the key from the object
120 if (value === undefined) {
122 key = this.getKey(value);
129 * Extracts the key from an object. This is a default implementation, it may be overridden
130 * @param {Object} o The object to get the key from
131 * @return {String} The key to use.
133 getKey: function(o) {
138 * Adds an item to the collection. Fires the {@link #add} event when complete.
139 * @param {String} key <p>The key to associate with the item, or the new item.</p>
140 * <p>If a {@link #getKey} implementation was specified for this HashMap,
141 * or if the key of the stored items is in a property called <tt><b>id</b></tt>,
142 * the HashMap will be able to <i>derive</i> the key for the new item.
143 * In this case just pass the new item in this parameter.</p>
144 * @param {Object} o The item to add.
145 * @return {Object} The item added.
147 add: function(key, value) {
151 if (arguments.length === 1) {
153 key = me.getKey(value);
156 if (me.containsKey(key)) {
157 me.replace(key, value);
160 data = me.getData(key, value);
165 me.fireEvent('add', me, key, value);
170 * Replaces an item in the hash. If the key doesn't exist, the
171 * {@link #add} method will be used.
172 * @param {String} key The key of the item.
173 * @param {Object} value The new value for the item.
174 * @return {Object} The new value of the item.
176 replace: function(key, value) {
181 if (!me.containsKey(key)) {
186 me.fireEvent('replace', me, key, value, old);
191 * Remove an item from the hash.
192 * @param {Object} o The value of the item to remove.
193 * @return {Boolean} True if the item was successfully removed.
195 remove: function(o) {
196 var key = this.findKey(o);
197 if (key !== undefined) {
198 return this.removeAtKey(key);
204 * Remove an item from the hash.
205 * @param {String} key The key to remove.
206 * @return {Boolean} True if the item was successfully removed.
208 removeAtKey: function(key) {
212 if (me.containsKey(key)) {
216 me.fireEvent('remove', me, key, value);
223 * Retrieves an item with a particular key.
224 * @param {String} key The key to lookup.
225 * @return {Object} The value at that key. If it doesn't exist, <tt>undefined</tt> is returned.
228 return this.map[key];
232 * Removes all items from the hash.
233 * @return {Ext.util.HashMap} this
235 clear: function(/* private */ initial) {
239 if (initial !== true) {
240 me.fireEvent('clear', me);
246 * Checks whether a key exists in the hash.
247 * @param {String} key The key to check for.
248 * @return {Boolean} True if they key exists in the hash.
250 containsKey: function(key) {
251 return this.map[key] !== undefined;
255 * Checks whether a value exists in the hash.
256 * @param {Object} value The value to check for.
257 * @return {Boolean} True if the value exists in the dictionary.
259 contains: function(value) {
260 return this.containsKey(this.findKey(value));
264 * Return all of the keys in the hash.
265 * @return {Array} An array of keys.
267 getKeys: function() {
268 return this.getArray(true);
272 * Return all of the values in the hash.
273 * @return {Array} An array of values.
275 getValues: function() {
276 return this.getArray(false);
280 * Gets either the keys/values in an array from the hash.
282 * @param {Boolean} isKey True to extract the keys, otherwise, the value
283 * @return {Array} An array of either keys/values from the hash.
285 getArray: function(isKey) {
290 if (map.hasOwnProperty(key)) {
291 arr.push(isKey ? key: map[key]);
298 * Executes the specified function once for each item in the hash.
299 * Returning false from the function will cease iteration.
301 * The paramaters passed to the function are:
302 * <div class="mdetail-params"><ul>
303 * <li><b>key</b> : String<p class="sub-desc">The key of the item</p></li>
304 * <li><b>value</b> : Number<p class="sub-desc">The value of the item</p></li>
305 * <li><b>length</b> : Number<p class="sub-desc">The total number of items in the hash</p></li>
307 * @param {Function} fn The function to execute.
308 * @param {Object} scope The scope to execute in. Defaults to <tt>this</tt>.
309 * @return {Ext.util.HashMap} this
311 each: function(fn, scope) {
312 // copy items so they may be removed during iteration.
313 var items = Ext.apply({}, this.map),
315 length = this.length;
317 scope = scope || this;
319 if (items.hasOwnProperty(key)) {
320 if (fn.call(scope, key, items[key], length) === false) {
329 * Performs a shallow copy on this hash.
330 * @return {Ext.util.HashMap} The new hash object.
333 var hash = new this.self(),
337 hash.suspendEvents();
339 if (map.hasOwnProperty(key)) {
340 hash.add(key, map[key]);
349 * Find the key for a value.
350 * @param {Object} value The value to find.
351 * @return {Object} The value of the item. Returns <tt>undefined</tt> if not found.
353 findKey: function(value) {
358 if (map.hasOwnProperty(key) && map[key] === value) {