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