Upgrade to ExtJS 4.0.0 - Released 04/26/2011
[extjs.git] / docs / source / MixedCollection.html
1 <!DOCTYPE html><html><head><title>Sencha Documentation Project</title><link rel="stylesheet" href="../reset.css" type="text/css"><link rel="stylesheet" href="../prettify.css" type="text/css"><link rel="stylesheet" href="../prettify_sa.css" type="text/css"><script type="text/javascript" src="../prettify.js"></script></head><body onload="prettyPrint()"><pre class="prettyprint"><pre><span id='Ext-util.MixedCollection-method-constructor'><span id='Ext-util.MixedCollection'>/**
2 </span></span> * @class Ext.util.MixedCollection
3  * &lt;p&gt;
4  * Represents a collection of a set of key and value pairs. Each key in the MixedCollection
5  * must be unique, the same key cannot exist twice. This collection is ordered, items in the
6  * collection can be accessed by index  or via the key. Newly added items are added to
7  * the end of the collection. This class is similar to {@link Ext.util.HashMap} however it
8  * is heavier and provides more functionality. Sample usage:
9  * &lt;pre&gt;&lt;code&gt;
10 var coll = new Ext.util.MixedCollection();
11 coll.add('key1', 'val1');
12 coll.add('key2', 'val2');
13 coll.add('key3', 'val3');
14
15 console.log(coll.get('key1')); // prints 'val1'
16 console.log(coll.indexOfKey('key3')); // prints 2
17  * &lt;/code&gt;&lt;/pre&gt;
18  *
19  * &lt;p&gt;
20  * The MixedCollection also has support for sorting and filtering of the values in the collection.
21  * &lt;pre&gt;&lt;code&gt;
22 var coll = new Ext.util.MixedCollection();
23 coll.add('key1', 100);
24 coll.add('key2', -100);
25 coll.add('key3', 17);
26 coll.add('key4', 0);
27 var biggerThanZero = coll.filterBy(function(value){
28     return value &gt; 0;
29 });
30 console.log(biggerThanZero.getCount()); // prints 2
31  * &lt;/code&gt;&lt;/pre&gt;
32  * &lt;/p&gt;
33  *
34  * @constructor
35  * @param {Boolean} allowFunctions Specify &lt;tt&gt;true&lt;/tt&gt; if the {@link #addAll}
36  * function should add function references to the collection. Defaults to
37  * &lt;tt&gt;false&lt;/tt&gt;.
38  * @param {Function} keyFn A function that can accept an item of the type(s) stored in this MixedCollection
39  * and return the key value for that item.  This is used when available to look up the key on items that
40  * were passed without an explicit key parameter to a MixedCollection method.  Passing this parameter is
41  * equivalent to providing an implementation for the {@link #getKey} method.
42  */
43 Ext.define('Ext.util.MixedCollection', {
44     extend: 'Ext.util.AbstractMixedCollection',
45     mixins: {
46         sortable: 'Ext.util.Sortable'
47     },
48
49     constructor: function() {
50         var me = this;
51         me.callParent(arguments);
52         me.addEvents('sort');
53         me.mixins.sortable.initSortable.call(me);
54     },
55
56     doSort: function(sorterFn) {
57         this.sortBy(sorterFn);
58     },
59
60 <span id='Ext-util.MixedCollection-method-_sort'>    /**
61 </span>     * @private
62      * Performs the actual sorting based on a direction and a sorting function. Internally,
63      * this creates a temporary array of all items in the MixedCollection, sorts it and then writes
64      * the sorted array data back into this.items and this.keys
65      * @param {String} property Property to sort by ('key', 'value', or 'index')
66      * @param {String} dir (optional) Direction to sort 'ASC' or 'DESC'. Defaults to 'ASC'.
67      * @param {Function} fn (optional) Comparison function that defines the sort order.
68      * Defaults to sorting by numeric value.
69      */
70     _sort : function(property, dir, fn){
71         var me = this,
72             i, len,
73             dsc   = String(dir).toUpperCase() == 'DESC' ? -1 : 1,
74
75             //this is a temporary array used to apply the sorting function
76             c     = [],
77             keys  = me.keys,
78             items = me.items;
79
80         //default to a simple sorter function if one is not provided
81         fn = fn || function(a, b) {
82             return a - b;
83         };
84
85         //copy all the items into a temporary array, which we will sort
86         for(i = 0, len = items.length; i &lt; len; i++){
87             c[c.length] = {
88                 key  : keys[i],
89                 value: items[i],
90                 index: i
91             };
92         }
93
94         //sort the temporary array
95         Ext.Array.sort(c, function(a, b){
96             var v = fn(a[property], b[property]) * dsc;
97             if(v === 0){
98                 v = (a.index &lt; b.index ? -1 : 1);
99             }
100             return v;
101         });
102
103         //copy the temporary array back into the main this.items and this.keys objects
104         for(i = 0, len = c.length; i &lt; len; i++){
105             items[i] = c[i].value;
106             keys[i]  = c[i].key;
107         }
108
109         me.fireEvent('sort', me);
110     },
111
112 <span id='Ext-util.MixedCollection-method-sortBy'>    /**
113 </span>     * Sorts the collection by a single sorter function
114      * @param {Function} sorterFn The function to sort by
115      */
116     sortBy: function(sorterFn) {
117         var me     = this,
118             items  = me.items,
119             keys   = me.keys,
120             length = items.length,
121             temp   = [],
122             i;
123
124         //first we create a copy of the items array so that we can sort it
125         for (i = 0; i &lt; length; i++) {
126             temp[i] = {
127                 key  : keys[i],
128                 value: items[i],
129                 index: i
130             };
131         }
132
133         Ext.Array.sort(temp, function(a, b) {
134             var v = sorterFn(a.value, b.value);
135             if (v === 0) {
136                 v = (a.index &lt; b.index ? -1 : 1);
137             }
138
139             return v;
140         });
141
142         //copy the temporary array back into the main this.items and this.keys objects
143         for (i = 0; i &lt; length; i++) {
144             items[i] = temp[i].value;
145             keys[i]  = temp[i].key;
146         }
147         
148         me.fireEvent('sort', me, items, keys);
149     },
150
151 <span id='Ext-util.MixedCollection-method-reorder'>    /**
152 </span>     * Reorders each of the items based on a mapping from old index to new index. Internally this
153      * just translates into a sort. The 'sort' event is fired whenever reordering has occured.
154      * @param {Object} mapping Mapping from old item index to new item index
155      */
156     reorder: function(mapping) {
157         var me = this,
158             items = me.items,
159             index = 0,
160             length = items.length,
161             order = [],
162             remaining = [],
163             oldIndex;
164
165         me.suspendEvents();
166
167         //object of {oldPosition: newPosition} reversed to {newPosition: oldPosition}
168         for (oldIndex in mapping) {
169             order[mapping[oldIndex]] = items[oldIndex];
170         }
171
172         for (index = 0; index &lt; length; index++) {
173             if (mapping[index] == undefined) {
174                 remaining.push(items[index]);
175             }
176         }
177
178         for (index = 0; index &lt; length; index++) {
179             if (order[index] == undefined) {
180                 order[index] = remaining.shift();
181             }
182         }
183
184         me.clear();
185         me.addAll(order);
186
187         me.resumeEvents();
188         me.fireEvent('sort', me);
189     },
190
191 <span id='Ext-util.MixedCollection-method-sortByKey'>    /**
192 </span>     * Sorts this collection by &lt;b&gt;key&lt;/b&gt;s.
193      * @param {String} direction (optional) 'ASC' or 'DESC'. Defaults to 'ASC'.
194      * @param {Function} fn (optional) Comparison function that defines the sort order.
195      * Defaults to sorting by case insensitive string.
196      */
197     sortByKey : function(dir, fn){
198         this._sort('key', dir, fn || function(a, b){
199             var v1 = String(a).toUpperCase(), v2 = String(b).toUpperCase();
200             return v1 &gt; v2 ? 1 : (v1 &lt; v2 ? -1 : 0);
201         });
202     }
203 });
204 </pre></pre></body></html>