source: Dev/trunk/src/client/dojo/_base/array.js @ 483

Last change on this file since 483 was 483, checked in by hendrikvanantwerpen, 11 years ago

Added Dojo 1.9.3 release.

File size: 11.7 KB
Line 
1define(["./kernel", "../has", "./lang"], function(dojo, has, lang){
2        // module:
3        //              dojo/_base/array
4
5        // our old simple function builder stuff
6        var cache = {}, u;
7
8        function buildFn(fn){
9                return cache[fn] = new Function("item", "index", "array", fn); // Function
10        }
11        // magic snippet: if(typeof fn == "string") fn = cache[fn] || buildFn(fn);
12
13        // every & some
14
15        function everyOrSome(some){
16                var every = !some;
17                return function(a, fn, o){
18                        var i = 0, l = a && a.length || 0, result;
19                        if(l && typeof a == "string") a = a.split("");
20                        if(typeof fn == "string") fn = cache[fn] || buildFn(fn);
21                        if(o){
22                                for(; i < l; ++i){
23                                        result = !fn.call(o, a[i], i, a);
24                                        if(some ^ result){
25                                                return !result;
26                                        }
27                                }
28                        }else{
29                                for(; i < l; ++i){
30                                        result = !fn(a[i], i, a);
31                                        if(some ^ result){
32                                                return !result;
33                                        }
34                                }
35                        }
36                        return every; // Boolean
37                };
38        }
39
40        // indexOf, lastIndexOf
41
42        function index(up){
43                var delta = 1, lOver = 0, uOver = 0;
44                if(!up){
45                        delta = lOver = uOver = -1;
46                }
47                return function(a, x, from, last){
48                        if(last && delta > 0){
49                                // TODO: why do we use a non-standard signature? why do we need "last"?
50                                return array.lastIndexOf(a, x, from);
51                        }
52                        var l = a && a.length || 0, end = up ? l + uOver : lOver, i;
53                        if(from === u){
54                                i = up ? lOver : l + uOver;
55                        }else{
56                                if(from < 0){
57                                        i = l + from;
58                                        if(i < 0){
59                                                i = lOver;
60                                        }
61                                }else{
62                                        i = from >= l ? l + uOver : from;
63                                }
64                        }
65                        if(l && typeof a == "string") a = a.split("");
66                        for(; i != end; i += delta){
67                                if(a[i] == x){
68                                        return i; // Number
69                                }
70                        }
71                        return -1; // Number
72                };
73        }
74
75        var array = {
76                // summary:
77                //              The Javascript v1.6 array extensions.
78
79                every: everyOrSome(false),
80                /*=====
81                 every: function(arr, callback, thisObject){
82                         // summary:
83                         //             Determines whether or not every item in arr satisfies the
84                         //             condition implemented by callback.
85                         // arr: Array|String
86                         //             the array to iterate on. If a string, operates on individual characters.
87                         // callback: Function|String
88                         //             a function is invoked with three arguments: item, index,
89                         //             and array and returns true if the condition is met.
90                         // thisObject: Object?
91                         //             may be used to scope the call to callback
92                         // returns: Boolean
93                         // description:
94                         //             This function corresponds to the JavaScript 1.6 Array.every() method, with one difference: when
95                         //             run over sparse arrays, this implementation passes the "holes" in the sparse array to
96                         //             the callback function with a value of undefined. JavaScript 1.6's every skips the holes in the sparse array.
97                         //             For more details, see:
98                         //             https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/every
99                         // example:
100                         //     |       // returns false
101                         //     |       array.every([1, 2, 3, 4], function(item){ return item>1; });
102                         // example:
103                         //     |       // returns true
104                         //     |       array.every([1, 2, 3, 4], function(item){ return item>0; });
105                 },
106                 =====*/
107
108                some: everyOrSome(true),
109                /*=====
110                some: function(arr, callback, thisObject){
111                        // summary:
112                        //              Determines whether or not any item in arr satisfies the
113                        //              condition implemented by callback.
114                        // arr: Array|String
115                        //              the array to iterate over. If a string, operates on individual characters.
116                        // callback: Function|String
117                        //              a function is invoked with three arguments: item, index,
118                        //              and array and returns true if the condition is met.
119                        // thisObject: Object?
120                        //              may be used to scope the call to callback
121                        // returns: Boolean
122                        // description:
123                        //              This function corresponds to the JavaScript 1.6 Array.some() method, with one difference: when
124                        //              run over sparse arrays, this implementation passes the "holes" in the sparse array to
125                        //              the callback function with a value of undefined. JavaScript 1.6's some skips the holes in the sparse array.
126                        //              For more details, see:
127                        //              https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/some
128                        // example:
129                        //      | // is true
130                        //      | array.some([1, 2, 3, 4], function(item){ return item>1; });
131                        // example:
132                        //      | // is false
133                        //      | array.some([1, 2, 3, 4], function(item){ return item<1; });
134                },
135                =====*/
136
137                indexOf: index(true),
138                /*=====
139                indexOf: function(arr, value, fromIndex, findLast){
140                        // summary:
141                        //              locates the first index of the provided value in the
142                        //              passed array. If the value is not found, -1 is returned.
143                        // description:
144                        //              This method corresponds to the JavaScript 1.6 Array.indexOf method, with two differences:
145                        //
146                        //              1. when run over sparse arrays, the Dojo function invokes the callback for every index
147                        //                 whereas JavaScript 1.6's indexOf skips the holes in the sparse array.
148                        //              2. uses equality (==) rather than strict equality (===)
149                        //
150                        //              For details on this method, see:
151                        //              https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/indexOf
152                        // arr: Array
153                        // value: Object
154                        // fromIndex: Integer?
155                        // findLast: Boolean?
156                        //              Makes indexOf() work like lastIndexOf().  Used internally; not meant for external usage.
157                        // returns: Number
158                },
159                =====*/
160
161                lastIndexOf: index(false),
162                /*=====
163                lastIndexOf: function(arr, value, fromIndex){
164                        // summary:
165                        //              locates the last index of the provided value in the passed
166                        //              array. If the value is not found, -1 is returned.
167                        // description:
168                        //              This method corresponds to the JavaScript 1.6 Array.lastIndexOf method, with two differences:
169                        //
170                        //              1. when run over sparse arrays, the Dojo function invokes the callback for every index
171                        //                 whereas JavaScript 1.6's lasIndexOf skips the holes in the sparse array.
172                        //              2. uses equality (==) rather than strict equality (===)
173                        //
174                        //              For details on this method, see:
175                        //              https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/lastIndexOf
176                        // arr: Array,
177                        // value: Object,
178                        // fromIndex: Integer?
179                        // returns: Number
180                },
181                =====*/
182
183                forEach: function(arr, callback, thisObject){
184                        // summary:
185                        //              for every item in arr, callback is invoked. Return values are ignored.
186                        //              If you want to break out of the loop, consider using array.every() or array.some().
187                        //              forEach does not allow breaking out of the loop over the items in arr.
188                        // arr:
189                        //              the array to iterate over. If a string, operates on individual characters.
190                        // callback:
191                        //              a function is invoked with three arguments: item, index, and array
192                        // thisObject:
193                        //              may be used to scope the call to callback
194                        // description:
195                        //              This function corresponds to the JavaScript 1.6 Array.forEach() method, with one difference: when
196                        //              run over sparse arrays, this implementation passes the "holes" in the sparse array to
197                        //              the callback function with a value of undefined. JavaScript 1.6's forEach skips the holes in the sparse array.
198                        //              For more details, see:
199                        //              https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/forEach
200                        // example:
201                        //      | // log out all members of the array:
202                        //      | array.forEach(
203                        //      |               [ "thinger", "blah", "howdy", 10 ],
204                        //      |               function(item){
205                        //      |                       console.log(item);
206                        //      |               }
207                        //      | );
208                        // example:
209                        //      | // log out the members and their indexes
210                        //      | array.forEach(
211                        //      |               [ "thinger", "blah", "howdy", 10 ],
212                        //      |               function(item, idx, arr){
213                        //      |                       console.log(item, "at index:", idx);
214                        //      |               }
215                        //      | );
216                        // example:
217                        //      | // use a scoped object member as the callback
218                        //      |
219                        //      | var obj = {
220                        //      |               prefix: "logged via obj.callback:",
221                        //      |               callback: function(item){
222                        //      |                       console.log(this.prefix, item);
223                        //      |               }
224                        //      | };
225                        //      |
226                        //      | // specifying the scope function executes the callback in that scope
227                        //      | array.forEach(
228                        //      |               [ "thinger", "blah", "howdy", 10 ],
229                        //      |               obj.callback,
230                        //      |               obj
231                        //      | );
232                        //      |
233                        //      | // alternately, we can accomplish the same thing with lang.hitch()
234                        //      | array.forEach(
235                        //      |               [ "thinger", "blah", "howdy", 10 ],
236                        //      |               lang.hitch(obj, "callback")
237                        //      | );
238                        // arr: Array|String
239                        // callback: Function|String
240                        // thisObject: Object?
241
242                        var i = 0, l = arr && arr.length || 0;
243                        if(l && typeof arr == "string") arr = arr.split("");
244                        if(typeof callback == "string") callback = cache[callback] || buildFn(callback);
245                        if(thisObject){
246                                for(; i < l; ++i){
247                                        callback.call(thisObject, arr[i], i, arr);
248                                }
249                        }else{
250                                for(; i < l; ++i){
251                                        callback(arr[i], i, arr);
252                                }
253                        }
254                },
255
256                map: function(arr, callback, thisObject, Ctr){
257                        // summary:
258                        //              applies callback to each element of arr and returns
259                        //              an Array with the results
260                        // arr: Array|String
261                        //              the array to iterate on. If a string, operates on
262                        //              individual characters.
263                        // callback: Function|String
264                        //              a function is invoked with three arguments, (item, index,
265                        //              array),  and returns a value
266                        // thisObject: Object?
267                        //              may be used to scope the call to callback
268                        // returns: Array
269                        // description:
270                        //              This function corresponds to the JavaScript 1.6 Array.map() method, with one difference: when
271                        //              run over sparse arrays, this implementation passes the "holes" in the sparse array to
272                        //              the callback function with a value of undefined. JavaScript 1.6's map skips the holes in the sparse array.
273                        //              For more details, see:
274                        //              https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/map
275                        // example:
276                        //      | // returns [2, 3, 4, 5]
277                        //      | array.map([1, 2, 3, 4], function(item){ return item+1 });
278
279                        // TODO: why do we have a non-standard signature here? do we need "Ctr"?
280                        var i = 0, l = arr && arr.length || 0, out = new (Ctr || Array)(l);
281                        if(l && typeof arr == "string") arr = arr.split("");
282                        if(typeof callback == "string") callback = cache[callback] || buildFn(callback);
283                        if(thisObject){
284                                for(; i < l; ++i){
285                                        out[i] = callback.call(thisObject, arr[i], i, arr);
286                                }
287                        }else{
288                                for(; i < l; ++i){
289                                        out[i] = callback(arr[i], i, arr);
290                                }
291                        }
292                        return out; // Array
293                },
294
295                filter: function(arr, callback, thisObject){
296                        // summary:
297                        //              Returns a new Array with those items from arr that match the
298                        //              condition implemented by callback.
299                        // arr: Array
300                        //              the array to iterate over.
301                        // callback: Function|String
302                        //              a function that is invoked with three arguments (item,
303                        //              index, array). The return of this function is expected to
304                        //              be a boolean which determines whether the passed-in item
305                        //              will be included in the returned array.
306                        // thisObject: Object?
307                        //              may be used to scope the call to callback
308                        // returns: Array
309                        // description:
310                        //              This function corresponds to the JavaScript 1.6 Array.filter() method, with one difference: when
311                        //              run over sparse arrays, this implementation passes the "holes" in the sparse array to
312                        //              the callback function with a value of undefined. JavaScript 1.6's filter skips the holes in the sparse array.
313                        //              For more details, see:
314                        //              https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/filter
315                        // example:
316                        //      | // returns [2, 3, 4]
317                        //      | array.filter([1, 2, 3, 4], function(item){ return item>1; });
318
319                        // TODO: do we need "Ctr" here like in map()?
320                        var i = 0, l = arr && arr.length || 0, out = [], value;
321                        if(l && typeof arr == "string") arr = arr.split("");
322                        if(typeof callback == "string") callback = cache[callback] || buildFn(callback);
323                        if(thisObject){
324                                for(; i < l; ++i){
325                                        value = arr[i];
326                                        if(callback.call(thisObject, value, i, arr)){
327                                                out.push(value);
328                                        }
329                                }
330                        }else{
331                                for(; i < l; ++i){
332                                        value = arr[i];
333                                        if(callback(value, i, arr)){
334                                                out.push(value);
335                                        }
336                                }
337                        }
338                        return out; // Array
339                },
340
341                clearCache: function(){
342                        cache = {};
343                }
344        };
345
346
347        has("extend-dojo") && lang.mixin(dojo, array);
348
349        return array;
350});
Note: See TracBrowser for help on using the repository browser.