Upgrade to ExtJS 4.0.7 - Released 10/19/2011
[extjs.git] / docs / source / AbstractMixedCollection.html
1 <!DOCTYPE html>
2 <html>
3 <head>
4   <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
5   <title>The source code</title>
6   <link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" />
7   <script type="text/javascript" src="../resources/prettify/prettify.js"></script>
8   <style type="text/css">
9     .highlight { display: block; background-color: #ddd; }
10   </style>
11   <script type="text/javascript">
12     function highlight() {
13       document.getElementById(location.hash.replace(/#/, "")).className = "highlight";
14     }
15   </script>
16 </head>
17 <body onload="prettyPrint(); highlight();">
18   <pre class="prettyprint lang-js"><span id='Ext-util-AbstractMixedCollection'>/**
19 </span> * @class Ext.util.AbstractMixedCollection
20  * @private
21  */
22 Ext.define('Ext.util.AbstractMixedCollection', {
23     requires: ['Ext.util.Filter'],
24
25     mixins: {
26         observable: 'Ext.util.Observable'
27     },
28
29     constructor: function(allowFunctions, keyFn) {
30         var me = this;
31
32         me.items = [];
33         me.map = {};
34         me.keys = [];
35         me.length = 0;
36
37         me.addEvents(
38 <span id='Ext-util-AbstractMixedCollection-event-clear'>            /**
39 </span>             * @event clear
40              * Fires when the collection is cleared.
41              */
42             'clear',
43
44 <span id='Ext-util-AbstractMixedCollection-event-add'>            /**
45 </span>             * @event add
46              * Fires when an item is added to the collection.
47              * @param {Number} index The index at which the item was added.
48              * @param {Object} o The item added.
49              * @param {String} key The key associated with the added item.
50              */
51             'add',
52
53 <span id='Ext-util-AbstractMixedCollection-event-replace'>            /**
54 </span>             * @event replace
55              * Fires when an item is replaced in the collection.
56              * @param {String} key he key associated with the new added.
57              * @param {Object} old The item being replaced.
58              * @param {Object} new The new item.
59              */
60             'replace',
61
62 <span id='Ext-util-AbstractMixedCollection-event-remove'>            /**
63 </span>             * @event remove
64              * Fires when an item is removed from the collection.
65              * @param {Object} o The item being removed.
66              * @param {String} key (optional) The key associated with the removed item.
67              */
68             'remove'
69         );
70
71         me.allowFunctions = allowFunctions === true;
72
73         if (keyFn) {
74             me.getKey = keyFn;
75         }
76
77         me.mixins.observable.constructor.call(me);
78     },
79
80 <span id='Ext-util-AbstractMixedCollection-cfg-allowFunctions'>    /**
81 </span>     * @cfg {Boolean} allowFunctions Specify &lt;tt&gt;true&lt;/tt&gt; if the {@link #addAll}
82      * function should add function references to the collection. Defaults to
83      * &lt;tt&gt;false&lt;/tt&gt;.
84      */
85     allowFunctions : false,
86
87 <span id='Ext-util-AbstractMixedCollection-method-add'>    /**
88 </span>     * Adds an item to the collection. Fires the {@link #add} event when complete.
89      * @param {String} key &lt;p&gt;The key to associate with the item, or the new item.&lt;/p&gt;
90      * &lt;p&gt;If a {@link #getKey} implementation was specified for this MixedCollection,
91      * or if the key of the stored items is in a property called &lt;tt&gt;&lt;b&gt;id&lt;/b&gt;&lt;/tt&gt;,
92      * the MixedCollection will be able to &lt;i&gt;derive&lt;/i&gt; the key for the new item.
93      * In this case just pass the new item in this parameter.&lt;/p&gt;
94      * @param {Object} o The item to add.
95      * @return {Object} The item added.
96      */
97     add : function(key, obj){
98         var me = this,
99             myObj = obj,
100             myKey = key,
101             old;
102
103         if (arguments.length == 1) {
104             myObj = myKey;
105             myKey = me.getKey(myObj);
106         }
107         if (typeof myKey != 'undefined' &amp;&amp; myKey !== null) {
108             old = me.map[myKey];
109             if (typeof old != 'undefined') {
110                 return me.replace(myKey, myObj);
111             }
112             me.map[myKey] = myObj;
113         }
114         me.length++;
115         me.items.push(myObj);
116         me.keys.push(myKey);
117         me.fireEvent('add', me.length - 1, myObj, myKey);
118         return myObj;
119     },
120
121 <span id='Ext-util-AbstractMixedCollection-method-getKey'>    /**
122 </span>      * MixedCollection has a generic way to fetch keys if you implement getKey.  The default implementation
123       * simply returns &lt;b&gt;&lt;code&gt;item.id&lt;/code&gt;&lt;/b&gt; but you can provide your own implementation
124       * to return a different value as in the following examples:&lt;pre&gt;&lt;code&gt;
125 // normal way
126 var mc = new Ext.util.MixedCollection();
127 mc.add(someEl.dom.id, someEl);
128 mc.add(otherEl.dom.id, otherEl);
129 //and so on
130
131 // using getKey
132 var mc = new Ext.util.MixedCollection();
133 mc.getKey = function(el){
134    return el.dom.id;
135 };
136 mc.add(someEl);
137 mc.add(otherEl);
138
139 // or via the constructor
140 var mc = new Ext.util.MixedCollection(false, function(el){
141    return el.dom.id;
142 });
143 mc.add(someEl);
144 mc.add(otherEl);
145      * &lt;/code&gt;&lt;/pre&gt;
146      * @param {Object} item The item for which to find the key.
147      * @return {Object} The key for the passed item.
148      */
149     getKey : function(o){
150          return o.id;
151     },
152
153 <span id='Ext-util-AbstractMixedCollection-method-replace'>    /**
154 </span>     * Replaces an item in the collection. Fires the {@link #replace} event when complete.
155      * @param {String} key &lt;p&gt;The key associated with the item to replace, or the replacement item.&lt;/p&gt;
156      * &lt;p&gt;If you supplied a {@link #getKey} implementation for this MixedCollection, or if the key
157      * of your stored items is in a property called &lt;tt&gt;&lt;b&gt;id&lt;/b&gt;&lt;/tt&gt;, then the MixedCollection
158      * will be able to &lt;i&gt;derive&lt;/i&gt; the key of the replacement item. If you want to replace an item
159      * with one having the same key value, then just pass the replacement item in this parameter.&lt;/p&gt;
160      * @param o {Object} o (optional) If the first parameter passed was a key, the item to associate
161      * with that key.
162      * @return {Object}  The new item.
163      */
164     replace : function(key, o){
165         var me = this,
166             old,
167             index;
168
169         if (arguments.length == 1) {
170             o = arguments[0];
171             key = me.getKey(o);
172         }
173         old = me.map[key];
174         if (typeof key == 'undefined' || key === null || typeof old == 'undefined') {
175              return me.add(key, o);
176         }
177         index = me.indexOfKey(key);
178         me.items[index] = o;
179         me.map[key] = o;
180         me.fireEvent('replace', key, old, o);
181         return o;
182     },
183
184 <span id='Ext-util-AbstractMixedCollection-method-addAll'>    /**
185 </span>     * Adds all elements of an Array or an Object to the collection.
186      * @param {Object/Array} objs An Object containing properties which will be added
187      * to the collection, or an Array of values, each of which are added to the collection.
188      * Functions references will be added to the collection if &lt;code&gt;{@link #allowFunctions}&lt;/code&gt;
189      * has been set to &lt;tt&gt;true&lt;/tt&gt;.
190      */
191     addAll : function(objs){
192         var me = this,
193             i = 0,
194             args,
195             len,
196             key;
197
198         if (arguments.length &gt; 1 || Ext.isArray(objs)) {
199             args = arguments.length &gt; 1 ? arguments : objs;
200             for (len = args.length; i &lt; len; i++) {
201                 me.add(args[i]);
202             }
203         } else {
204             for (key in objs) {
205                 if (objs.hasOwnProperty(key)) {
206                     if (me.allowFunctions || typeof objs[key] != 'function') {
207                         me.add(key, objs[key]);
208                     }
209                 }
210             }
211         }
212     },
213
214 <span id='Ext-util-AbstractMixedCollection-method-each'>    /**
215 </span>     * Executes the specified function once for every item in the collection, passing the following arguments:
216      * &lt;div class=&quot;mdetail-params&quot;&gt;&lt;ul&gt;
217      * &lt;li&gt;&lt;b&gt;item&lt;/b&gt; : Mixed&lt;p class=&quot;sub-desc&quot;&gt;The collection item&lt;/p&gt;&lt;/li&gt;
218      * &lt;li&gt;&lt;b&gt;index&lt;/b&gt; : Number&lt;p class=&quot;sub-desc&quot;&gt;The item's index&lt;/p&gt;&lt;/li&gt;
219      * &lt;li&gt;&lt;b&gt;length&lt;/b&gt; : Number&lt;p class=&quot;sub-desc&quot;&gt;The total number of items in the collection&lt;/p&gt;&lt;/li&gt;
220      * &lt;/ul&gt;&lt;/div&gt;
221      * The function should return a boolean value. Returning false from the function will stop the iteration.
222      * @param {Function} fn The function to execute for each item.
223      * @param {Object} scope (optional) The scope (&lt;code&gt;this&lt;/code&gt; reference) in which the function is executed. Defaults to the current item in the iteration.
224      */
225     each : function(fn, scope){
226         var items = [].concat(this.items), // each safe for removal
227             i = 0,
228             len = items.length,
229             item;
230
231         for (; i &lt; len; i++) {
232             item = items[i];
233             if (fn.call(scope || item, item, i, len) === false) {
234                 break;
235             }
236         }
237     },
238
239 <span id='Ext-util-AbstractMixedCollection-method-eachKey'>    /**
240 </span>     * Executes the specified function once for every key in the collection, passing each
241      * key, and its associated item as the first two parameters.
242      * @param {Function} fn The function to execute for each item.
243      * @param {Object} scope (optional) The scope (&lt;code&gt;this&lt;/code&gt; reference) in which the function is executed. Defaults to the browser window.
244      */
245     eachKey : function(fn, scope){
246         var keys = this.keys,
247             items = this.items,
248             i = 0,
249             len = keys.length;
250
251         for (; i &lt; len; i++) {
252             fn.call(scope || window, keys[i], items[i], i, len);
253         }
254     },
255
256 <span id='Ext-util-AbstractMixedCollection-method-findBy'>    /**
257 </span>     * Returns the first item in the collection which elicits a true return value from the
258      * passed selection function.
259      * @param {Function} fn The selection function to execute for each item.
260      * @param {Object} scope (optional) The scope (&lt;code&gt;this&lt;/code&gt; reference) in which the function is executed. Defaults to the browser window.
261      * @return {Object} The first item in the collection which returned true from the selection function, or null if none was found
262      */
263     findBy : function(fn, scope) {
264         var keys = this.keys,
265             items = this.items,
266             i = 0,
267             len = items.length;
268
269         for (; i &lt; len; i++) {
270             if (fn.call(scope || window, items[i], keys[i])) {
271                 return items[i];
272             }
273         }
274         return null;
275     },
276
277     //&lt;deprecated since=&quot;0.99&quot;&gt;
278     find : function() {
279         if (Ext.isDefined(Ext.global.console)) {
280             Ext.global.console.warn('Ext.util.MixedCollection: find has been deprecated. Use findBy instead.');
281         }
282         return this.findBy.apply(this, arguments);
283     },
284     //&lt;/deprecated&gt;
285
286 <span id='Ext-util-AbstractMixedCollection-method-insert'>    /**
287 </span>     * Inserts an item at the specified index in the collection. Fires the {@link #add} event when complete.
288      * @param {Number} index The index to insert the item at.
289      * @param {String} key The key to associate with the new item, or the item itself.
290      * @param {Object} o (optional) If the second parameter was a key, the new item.
291      * @return {Object} The item inserted.
292      */
293     insert : function(index, key, obj){
294         var me = this,
295             myKey = key,
296             myObj = obj;
297
298         if (arguments.length == 2) {
299             myObj = myKey;
300             myKey = me.getKey(myObj);
301         }
302         if (me.containsKey(myKey)) {
303             me.suspendEvents();
304             me.removeAtKey(myKey);
305             me.resumeEvents();
306         }
307         if (index &gt;= me.length) {
308             return me.add(myKey, myObj);
309         }
310         me.length++;
311         Ext.Array.splice(me.items, index, 0, myObj);
312         if (typeof myKey != 'undefined' &amp;&amp; myKey !== null) {
313             me.map[myKey] = myObj;
314         }
315         Ext.Array.splice(me.keys, index, 0, myKey);
316         me.fireEvent('add', index, myObj, myKey);
317         return myObj;
318     },
319
320 <span id='Ext-util-AbstractMixedCollection-method-remove'>    /**
321 </span>     * Remove an item from the collection.
322      * @param {Object} o The item to remove.
323      * @return {Object} The item removed or false if no item was removed.
324      */
325     remove : function(o){
326         return this.removeAt(this.indexOf(o));
327     },
328
329 <span id='Ext-util-AbstractMixedCollection-method-removeAll'>    /**
330 </span>     * Remove all items in the passed array from the collection.
331      * @param {Array} items An array of items to be removed.
332      * @return {Ext.util.MixedCollection} this object
333      */
334     removeAll : function(items){
335         Ext.each(items || [], function(item) {
336             this.remove(item);
337         }, this);
338
339         return this;
340     },
341
342 <span id='Ext-util-AbstractMixedCollection-method-removeAt'>    /**
343 </span>     * Remove an item from a specified index in the collection. Fires the {@link #remove} event when complete.
344      * @param {Number} index The index within the collection of the item to remove.
345      * @return {Object} The item removed or false if no item was removed.
346      */
347     removeAt : function(index){
348         var me = this,
349             o,
350             key;
351
352         if (index &lt; me.length &amp;&amp; index &gt;= 0) {
353             me.length--;
354             o = me.items[index];
355             Ext.Array.erase(me.items, index, 1);
356             key = me.keys[index];
357             if (typeof key != 'undefined') {
358                 delete me.map[key];
359             }
360             Ext.Array.erase(me.keys, index, 1);
361             me.fireEvent('remove', o, key);
362             return o;
363         }
364         return false;
365     },
366
367 <span id='Ext-util-AbstractMixedCollection-method-removeAtKey'>    /**
368 </span>     * Removed an item associated with the passed key fom the collection.
369      * @param {String} key The key of the item to remove.
370      * @return {Object} The item removed or false if no item was removed.
371      */
372     removeAtKey : function(key){
373         return this.removeAt(this.indexOfKey(key));
374     },
375
376 <span id='Ext-util-AbstractMixedCollection-method-getCount'>    /**
377 </span>     * Returns the number of items in the collection.
378      * @return {Number} the number of items in the collection.
379      */
380     getCount : function(){
381         return this.length;
382     },
383
384 <span id='Ext-util-AbstractMixedCollection-method-indexOf'>    /**
385 </span>     * Returns index within the collection of the passed Object.
386      * @param {Object} o The item to find the index of.
387      * @return {Number} index of the item. Returns -1 if not found.
388      */
389     indexOf : function(o){
390         return Ext.Array.indexOf(this.items, o);
391     },
392
393 <span id='Ext-util-AbstractMixedCollection-method-indexOfKey'>    /**
394 </span>     * Returns index within the collection of the passed key.
395      * @param {String} key The key to find the index of.
396      * @return {Number} index of the key.
397      */
398     indexOfKey : function(key){
399         return Ext.Array.indexOf(this.keys, key);
400     },
401
402 <span id='Ext-util-AbstractMixedCollection-method-get'>    /**
403 </span>     * Returns the item associated with the passed key OR index.
404      * Key has priority over index.  This is the equivalent
405      * of calling {@link #getByKey} first, then if nothing matched calling {@link #getAt}.
406      * @param {String/Number} key The key or index of the item.
407      * @return {Object} If the item is found, returns the item.  If the item was not found, returns &lt;tt&gt;undefined&lt;/tt&gt;.
408      * If an item was found, but is a Class, returns &lt;tt&gt;null&lt;/tt&gt;.
409      */
410     get : function(key) {
411         var me = this,
412             mk = me.map[key],
413             item = mk !== undefined ? mk : (typeof key == 'number') ? me.items[key] : undefined;
414         return typeof item != 'function' || me.allowFunctions ? item : null; // for prototype!
415     },
416
417 <span id='Ext-util-AbstractMixedCollection-method-getAt'>    /**
418 </span>     * Returns the item at the specified index.
419      * @param {Number} index The index of the item.
420      * @return {Object} The item at the specified index.
421      */
422     getAt : function(index) {
423         return this.items[index];
424     },
425
426 <span id='Ext-util-AbstractMixedCollection-method-getByKey'>    /**
427 </span>     * Returns the item associated with the passed key.
428      * @param {String/Number} key The key of the item.
429      * @return {Object} The item associated with the passed key.
430      */
431     getByKey : function(key) {
432         return this.map[key];
433     },
434
435 <span id='Ext-util-AbstractMixedCollection-method-contains'>    /**
436 </span>     * Returns true if the collection contains the passed Object as an item.
437      * @param {Object} o  The Object to look for in the collection.
438      * @return {Boolean} True if the collection contains the Object as an item.
439      */
440     contains : function(o){
441         return Ext.Array.contains(this.items, o);
442     },
443
444 <span id='Ext-util-AbstractMixedCollection-method-containsKey'>    /**
445 </span>     * Returns true if the collection contains the passed Object as a key.
446      * @param {String} key The key to look for in the collection.
447      * @return {Boolean} True if the collection contains the Object as a key.
448      */
449     containsKey : function(key){
450         return typeof this.map[key] != 'undefined';
451     },
452
453 <span id='Ext-util-AbstractMixedCollection-method-clear'>    /**
454 </span>     * Removes all items from the collection.  Fires the {@link #clear} event when complete.
455      */
456     clear : function(){
457         var me = this;
458
459         me.length = 0;
460         me.items = [];
461         me.keys = [];
462         me.map = {};
463         me.fireEvent('clear');
464     },
465
466 <span id='Ext-util-AbstractMixedCollection-method-first'>    /**
467 </span>     * Returns the first item in the collection.
468      * @return {Object} the first item in the collection..
469      */
470     first : function() {
471         return this.items[0];
472     },
473
474 <span id='Ext-util-AbstractMixedCollection-method-last'>    /**
475 </span>     * Returns the last item in the collection.
476      * @return {Object} the last item in the collection..
477      */
478     last : function() {
479         return this.items[this.length - 1];
480     },
481
482 <span id='Ext-util-AbstractMixedCollection-method-sum'>    /**
483 </span>     * Collects all of the values of the given property and returns their sum
484      * @param {String} property The property to sum by
485      * @param {String} [root] 'root' property to extract the first argument from. This is used mainly when
486      * summing fields in records, where the fields are all stored inside the 'data' object
487      * @param {Number} [start=0] The record index to start at
488      * @param {Number} [end=-1] The record index to end at
489      * @return {Number} The total
490      */
491     sum: function(property, root, start, end) {
492         var values = this.extractValues(property, root),
493             length = values.length,
494             sum    = 0,
495             i;
496
497         start = start || 0;
498         end   = (end || end === 0) ? end : length - 1;
499
500         for (i = start; i &lt;= end; i++) {
501             sum += values[i];
502         }
503
504         return sum;
505     },
506
507 <span id='Ext-util-AbstractMixedCollection-method-collect'>    /**
508 </span>     * Collects unique values of a particular property in this MixedCollection
509      * @param {String} property The property to collect on
510      * @param {String} root (optional) 'root' property to extract the first argument from. This is used mainly when
511      * summing fields in records, where the fields are all stored inside the 'data' object
512      * @param {Boolean} allowBlank (optional) Pass true to allow null, undefined or empty string values
513      * @return {Array} The unique values
514      */
515     collect: function(property, root, allowNull) {
516         var values = this.extractValues(property, root),
517             length = values.length,
518             hits   = {},
519             unique = [],
520             value, strValue, i;
521
522         for (i = 0; i &lt; length; i++) {
523             value = values[i];
524             strValue = String(value);
525
526             if ((allowNull || !Ext.isEmpty(value)) &amp;&amp; !hits[strValue]) {
527                 hits[strValue] = true;
528                 unique.push(value);
529             }
530         }
531
532         return unique;
533     },
534
535 <span id='Ext-util-AbstractMixedCollection-method-extractValues'>    /**
536 </span>     * @private
537      * Extracts all of the given property values from the items in the MC. Mainly used as a supporting method for
538      * functions like sum and collect.
539      * @param {String} property The property to extract
540      * @param {String} root (optional) 'root' property to extract the first argument from. This is used mainly when
541      * extracting field data from Model instances, where the fields are stored inside the 'data' object
542      * @return {Array} The extracted values
543      */
544     extractValues: function(property, root) {
545         var values = this.items;
546
547         if (root) {
548             values = Ext.Array.pluck(values, root);
549         }
550
551         return Ext.Array.pluck(values, property);
552     },
553
554 <span id='Ext-util-AbstractMixedCollection-method-getRange'>    /**
555 </span>     * Returns a range of items in this collection
556      * @param {Number} startIndex (optional) The starting index. Defaults to 0.
557      * @param {Number} endIndex (optional) The ending index. Defaults to the last item.
558      * @return {Array} An array of items
559      */
560     getRange : function(start, end){
561         var me = this,
562             items = me.items,
563             range = [],
564             i;
565
566         if (items.length &lt; 1) {
567             return range;
568         }
569
570         start = start || 0;
571         end = Math.min(typeof end == 'undefined' ? me.length - 1 : end, me.length - 1);
572         if (start &lt;= end) {
573             for (i = start; i &lt;= end; i++) {
574                 range[range.length] = items[i];
575             }
576         } else {
577             for (i = start; i &gt;= end; i--) {
578                 range[range.length] = items[i];
579             }
580         }
581         return range;
582     },
583
584 <span id='Ext-util-AbstractMixedCollection-method-filter'>    /**
585 </span>     * &lt;p&gt;Filters the objects in this collection by a set of {@link Ext.util.Filter Filter}s, or by a single
586      * property/value pair with optional parameters for substring matching and case sensitivity. See
587      * {@link Ext.util.Filter Filter} for an example of using Filter objects (preferred). Alternatively,
588      * MixedCollection can be easily filtered by property like this:&lt;/p&gt;
589 &lt;pre&gt;&lt;code&gt;
590 //create a simple store with a few people defined
591 var people = new Ext.util.MixedCollection();
592 people.addAll([
593     {id: 1, age: 25, name: 'Ed'},
594     {id: 2, age: 24, name: 'Tommy'},
595     {id: 3, age: 24, name: 'Arne'},
596     {id: 4, age: 26, name: 'Aaron'}
597 ]);
598
599 //a new MixedCollection containing only the items where age == 24
600 var middleAged = people.filter('age', 24);
601 &lt;/code&gt;&lt;/pre&gt;
602      *
603      *
604      * @param {Ext.util.Filter[]/String} property A property on your objects, or an array of {@link Ext.util.Filter Filter} objects
605      * @param {String/RegExp} value Either string that the property values
606      * should start with or a RegExp to test against the property
607      * @param {Boolean} [anyMatch=false] True to match any part of the string, not just the beginning
608      * @param {Boolean} [caseSensitive=false] True for case sensitive comparison.
609      * @return {Ext.util.MixedCollection} The new filtered collection
610      */
611     filter : function(property, value, anyMatch, caseSensitive) {
612         var filters = [],
613             filterFn;
614
615         //support for the simple case of filtering by property/value
616         if (Ext.isString(property)) {
617             filters.push(Ext.create('Ext.util.Filter', {
618                 property     : property,
619                 value        : value,
620                 anyMatch     : anyMatch,
621                 caseSensitive: caseSensitive
622             }));
623         } else if (Ext.isArray(property) || property instanceof Ext.util.Filter) {
624             filters = filters.concat(property);
625         }
626
627         //at this point we have an array of zero or more Ext.util.Filter objects to filter with,
628         //so here we construct a function that combines these filters by ANDing them together
629         filterFn = function(record) {
630             var isMatch = true,
631                 length = filters.length,
632                 i;
633
634             for (i = 0; i &lt; length; i++) {
635                 var filter = filters[i],
636                     fn     = filter.filterFn,
637                     scope  = filter.scope;
638
639                 isMatch = isMatch &amp;&amp; fn.call(scope, record);
640             }
641
642             return isMatch;
643         };
644
645         return this.filterBy(filterFn);
646     },
647
648 <span id='Ext-util-AbstractMixedCollection-method-filterBy'>    /**
649 </span>     * Filter by a function. Returns a &lt;i&gt;new&lt;/i&gt; collection that has been filtered.
650      * The passed function will be called with each object in the collection.
651      * If the function returns true, the value is included otherwise it is filtered.
652      * @param {Function} fn The function to be called, it will receive the args o (the object), k (the key)
653      * @param {Object} scope (optional) The scope (&lt;code&gt;this&lt;/code&gt; reference) in which the function is executed. Defaults to this MixedCollection.
654      * @return {Ext.util.MixedCollection} The new filtered collection
655      */
656     filterBy : function(fn, scope) {
657         var me = this,
658             newMC  = new this.self(),
659             keys   = me.keys,
660             items  = me.items,
661             length = items.length,
662             i;
663
664         newMC.getKey = me.getKey;
665
666         for (i = 0; i &lt; length; i++) {
667             if (fn.call(scope || me, items[i], keys[i])) {
668                 newMC.add(keys[i], items[i]);
669             }
670         }
671
672         return newMC;
673     },
674
675 <span id='Ext-util-AbstractMixedCollection-method-findIndex'>    /**
676 </span>     * Finds the index of the first matching object in this collection by a specific property/value.
677      * @param {String} property The name of a property on your objects.
678      * @param {String/RegExp} value A string that the property values
679      * should start with or a RegExp to test against the property.
680      * @param {Number} [start=0] The index to start searching at.
681      * @param {Boolean} [anyMatch=false] True to match any part of the string, not just the beginning.
682      * @param {Boolean} [caseSensitive=false] True for case sensitive comparison.
683      * @return {Number} The matched index or -1
684      */
685     findIndex : function(property, value, start, anyMatch, caseSensitive){
686         if(Ext.isEmpty(value, false)){
687             return -1;
688         }
689         value = this.createValueMatcher(value, anyMatch, caseSensitive);
690         return this.findIndexBy(function(o){
691             return o &amp;&amp; value.test(o[property]);
692         }, null, start);
693     },
694
695 <span id='Ext-util-AbstractMixedCollection-method-findIndexBy'>    /**
696 </span>     * Find the index of the first matching object in this collection by a function.
697      * If the function returns &lt;i&gt;true&lt;/i&gt; it is considered a match.
698      * @param {Function} fn The function to be called, it will receive the args o (the object), k (the key).
699      * @param {Object} [scope] The scope (&lt;code&gt;this&lt;/code&gt; reference) in which the function is executed. Defaults to this MixedCollection.
700      * @param {Number} [start=0] The index to start searching at.
701      * @return {Number} The matched index or -1
702      */
703     findIndexBy : function(fn, scope, start){
704         var me = this,
705             keys = me.keys,
706             items = me.items,
707             i = start || 0,
708             len = items.length;
709
710         for (; i &lt; len; i++) {
711             if (fn.call(scope || me, items[i], keys[i])) {
712                 return i;
713             }
714         }
715         return -1;
716     },
717
718 <span id='Ext-util-AbstractMixedCollection-method-createValueMatcher'>    /**
719 </span>     * Returns a regular expression based on the given value and matching options. This is used internally for finding and filtering,
720      * and by Ext.data.Store#filter
721      * @private
722      * @param {String} value The value to create the regex for. This is escaped using Ext.escapeRe
723      * @param {Boolean} anyMatch True to allow any match - no regex start/end line anchors will be added. Defaults to false
724      * @param {Boolean} caseSensitive True to make the regex case sensitive (adds 'i' switch to regex). Defaults to false.
725      * @param {Boolean} exactMatch True to force exact match (^ and $ characters added to the regex). Defaults to false. Ignored if anyMatch is true.
726      */
727     createValueMatcher : function(value, anyMatch, caseSensitive, exactMatch) {
728         if (!value.exec) { // not a regex
729             var er = Ext.String.escapeRegex;
730             value = String(value);
731
732             if (anyMatch === true) {
733                 value = er(value);
734             } else {
735                 value = '^' + er(value);
736                 if (exactMatch === true) {
737                     value += '$';
738                 }
739             }
740             value = new RegExp(value, caseSensitive ? '' : 'i');
741         }
742         return value;
743     },
744
745 <span id='Ext-util-AbstractMixedCollection-method-clone'>    /**
746 </span>     * Creates a shallow copy of this collection
747      * @return {Ext.util.MixedCollection}
748      */
749     clone : function() {
750         var me = this,
751             copy = new this.self(),
752             keys = me.keys,
753             items = me.items,
754             i = 0,
755             len = items.length;
756
757         for(; i &lt; len; i++){
758             copy.add(keys[i], items[i]);
759         }
760         copy.getKey = me.getKey;
761         return copy;
762     }
763 });
764 </pre>
765 </body>
766 </html>