Upgrade to ExtJS 4.0.7 - Released 10/19/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="../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-MixedCollection'>/**
19 </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 Ext.define('Ext.util.MixedCollection', {
52     extend: 'Ext.util.AbstractMixedCollection',
53     mixins: {
54         sortable: 'Ext.util.Sortable'
55     },
56
57 <span id='Ext-util-MixedCollection-method-constructor'>    /**
58 </span>     * Creates new MixedCollection.
59      * @param {Boolean} allowFunctions Specify &lt;tt&gt;true&lt;/tt&gt; if the {@link #addAll}
60      * function should add function references to the collection. Defaults to
61      * &lt;tt&gt;false&lt;/tt&gt;.
62      * @param {Function} keyFn A function that can accept an item of the type(s) stored in this MixedCollection
63      * and return the key value for that item.  This is used when available to look up the key on items that
64      * were passed without an explicit key parameter to a MixedCollection method.  Passing this parameter is
65      * equivalent to providing an implementation for the {@link #getKey} method.
66      */
67     constructor: function() {
68         var me = this;
69         me.callParent(arguments);
70         me.addEvents('sort');
71         me.mixins.sortable.initSortable.call(me);
72     },
73
74     doSort: function(sorterFn) {
75         this.sortBy(sorterFn);
76     },
77
78 <span id='Ext-util-MixedCollection-method-_sort'>    /**
79 </span>     * @private
80      * Performs the actual sorting based on a direction and a sorting function. Internally,
81      * this creates a temporary array of all items in the MixedCollection, sorts it and then writes
82      * the sorted array data back into this.items and this.keys
83      * @param {String} property Property to sort by ('key', 'value', or 'index')
84      * @param {String} dir (optional) Direction to sort 'ASC' or 'DESC'. Defaults to 'ASC'.
85      * @param {Function} fn (optional) Comparison function that defines the sort order.
86      * Defaults to sorting by numeric value.
87      */
88     _sort : function(property, dir, fn){
89         var me = this,
90             i, len,
91             dsc   = String(dir).toUpperCase() == 'DESC' ? -1 : 1,
92
93             //this is a temporary array used to apply the sorting function
94             c     = [],
95             keys  = me.keys,
96             items = me.items;
97
98         //default to a simple sorter function if one is not provided
99         fn = fn || function(a, b) {
100             return a - b;
101         };
102
103         //copy all the items into a temporary array, which we will sort
104         for(i = 0, len = items.length; i &lt; len; i++){
105             c[c.length] = {
106                 key  : keys[i],
107                 value: items[i],
108                 index: i
109             };
110         }
111
112         //sort the temporary array
113         Ext.Array.sort(c, function(a, b){
114             var v = fn(a[property], b[property]) * dsc;
115             if(v === 0){
116                 v = (a.index &lt; b.index ? -1 : 1);
117             }
118             return v;
119         });
120
121         //copy the temporary array back into the main this.items and this.keys objects
122         for(i = 0, len = c.length; i &lt; len; i++){
123             items[i] = c[i].value;
124             keys[i]  = c[i].key;
125         }
126
127         me.fireEvent('sort', me);
128     },
129
130 <span id='Ext-util-MixedCollection-method-sortBy'>    /**
131 </span>     * Sorts the collection by a single sorter function
132      * @param {Function} sorterFn The function to sort by
133      */
134     sortBy: function(sorterFn) {
135         var me     = this,
136             items  = me.items,
137             keys   = me.keys,
138             length = items.length,
139             temp   = [],
140             i;
141
142         //first we create a copy of the items array so that we can sort it
143         for (i = 0; i &lt; length; i++) {
144             temp[i] = {
145                 key  : keys[i],
146                 value: items[i],
147                 index: i
148             };
149         }
150
151         Ext.Array.sort(temp, function(a, b) {
152             var v = sorterFn(a.value, b.value);
153             if (v === 0) {
154                 v = (a.index &lt; b.index ? -1 : 1);
155             }
156
157             return v;
158         });
159
160         //copy the temporary array back into the main this.items and this.keys objects
161         for (i = 0; i &lt; length; i++) {
162             items[i] = temp[i].value;
163             keys[i]  = temp[i].key;
164         }
165         
166         me.fireEvent('sort', me, items, keys);
167     },
168
169 <span id='Ext-util-MixedCollection-method-reorder'>    /**
170 </span>     * Reorders each of the items based on a mapping from old index to new index. Internally this
171      * just translates into a sort. The 'sort' event is fired whenever reordering has occured.
172      * @param {Object} mapping Mapping from old item index to new item index
173      */
174     reorder: function(mapping) {
175         var me = this,
176             items = me.items,
177             index = 0,
178             length = items.length,
179             order = [],
180             remaining = [],
181             oldIndex;
182
183         me.suspendEvents();
184
185         //object of {oldPosition: newPosition} reversed to {newPosition: oldPosition}
186         for (oldIndex in mapping) {
187             order[mapping[oldIndex]] = items[oldIndex];
188         }
189
190         for (index = 0; index &lt; length; index++) {
191             if (mapping[index] == undefined) {
192                 remaining.push(items[index]);
193             }
194         }
195
196         for (index = 0; index &lt; length; index++) {
197             if (order[index] == undefined) {
198                 order[index] = remaining.shift();
199             }
200         }
201
202         me.clear();
203         me.addAll(order);
204
205         me.resumeEvents();
206         me.fireEvent('sort', me);
207     },
208
209 <span id='Ext-util-MixedCollection-method-sortByKey'>    /**
210 </span>     * Sorts this collection by &lt;b&gt;key&lt;/b&gt;s.
211      * @param {String} direction (optional) 'ASC' or 'DESC'. Defaults to 'ASC'.
212      * @param {Function} fn (optional) Comparison function that defines the sort order.
213      * Defaults to sorting by case insensitive string.
214      */
215     sortByKey : function(dir, fn){
216         this._sort('key', dir, fn || function(a, b){
217             var v1 = String(a).toUpperCase(), v2 = String(b).toUpperCase();
218             return v1 &gt; v2 ? 1 : (v1 &lt; v2 ? -1 : 0);
219         });
220     }
221 });
222 </pre>
223 </body>
224 </html>