Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 1
YUI.add('array-extras', function (Y, NAME) {
2
 
3
/**
4
Adds additional utility methods to the `Y.Array` class.
5
 
6
@module collection
7
@submodule array-extras
8
**/
9
 
10
var A          = Y.Array,
11
    L          = Y.Lang,
12
    ArrayProto = Array.prototype;
13
 
14
/**
15
Returns the index of the last item in the array that contains the specified
16
value, or `-1` if the value isn't found.
17
 
18
@method lastIndexOf
19
@param {Array} a Array to search in.
20
@param {Any} val Value to search for.
21
@param {Number} [fromIndex] Index at which to start searching backwards.
22
  Defaults to the array's length - 1. If negative, it will be taken as an offset
23
  from the end of the array. If the calculated index is less than 0, the array
24
  will not be searched and `-1` will be returned.
25
@return {Number} Index of the item that contains the value, or `-1` if not
26
  found.
27
@static
28
@for Array
29
**/
30
A.lastIndexOf = L._isNative(ArrayProto.lastIndexOf) ?
31
    function(a, val, fromIndex) {
32
        // An undefined fromIndex is still considered a value by some (all?)
33
        // native implementations, so we can't pass it unless it's actually
34
        // specified.
35
        return fromIndex || fromIndex === 0 ? a.lastIndexOf(val, fromIndex) :
36
                a.lastIndexOf(val);
37
    } :
38
    function(a, val, fromIndex) {
39
        var len = a.length,
40
            i   = len - 1;
41
 
42
        if (fromIndex || fromIndex === 0) {
43
            i = Math.min(fromIndex < 0 ? len + fromIndex : fromIndex, len);
44
        }
45
 
46
        if (i > -1 && len > 0) {
47
            for (; i > -1; --i) {
48
                if (i in a && a[i] === val) {
49
                    return i;
50
                }
51
            }
52
        }
53
 
54
        return -1;
55
    };
56
 
57
/**
58
Returns a copy of the input array with duplicate items removed.
59
 
60
Note: If the input array only contains strings, the `Y.Array.dedupe()` method is
61
a much faster alternative.
62
 
63
@method unique
64
@param {Array} array Array to dedupe.
65
@param {Function} [testFn] Custom function to use to test the equality of two
66
    values. A truthy return value indicates that the values are equal. A falsy
67
    return value indicates that the values are not equal.
68
 
69
    @param {Any} testFn.a First value to compare.
70
    @param {Any} testFn.b Second value to compare.
71
    @param {Number} testFn.index Index of the current item in the original
72
        array.
73
    @param {Array} testFn.array The original array.
74
    @return {Boolean} _true_ if the items are equal, _false_ otherwise.
75
 
76
@return {Array} Copy of the input array with duplicate items removed.
77
@static
78
**/
79
A.unique = function (array, testFn) {
80
    var i       = 0,
81
        len     = array.length,
82
        results = [],
83
        j, result, resultLen, value;
84
 
85
    // Note the label here. It's used to jump out of the inner loop when a value
86
    // is not unique.
87
    outerLoop: for (; i < len; i++) {
88
        value = array[i];
89
 
90
        // For each value in the input array, iterate through the result array
91
        // and check for uniqueness against each result value.
92
        for (j = 0, resultLen = results.length; j < resultLen; j++) {
93
            result = results[j];
94
 
95
            // If the test function returns true or there's no test function and
96
            // the value equals the current result item, stop iterating over the
97
            // results and continue to the next value in the input array.
98
            if (testFn) {
99
                if (testFn.call(array, value, result, i, array)) {
100
                    continue outerLoop;
101
                }
102
            } else if (value === result) {
103
                continue outerLoop;
104
            }
105
        }
106
 
107
        // If we get this far, that means the current value is not already in
108
        // the result array, so add it.
109
        results.push(value);
110
    }
111
 
112
    return results;
113
};
114
 
115
/**
116
Executes the supplied function on each item in the array. Returns a new array
117
containing the items for which the supplied function returned a truthy value.
118
 
119
@method filter
120
@param {Array} a Array to filter.
121
@param {Function} f Function to execute on each item.
122
@param {Object} [o] Optional context object.
123
@return {Array} Array of items for which the supplied function returned a
124
  truthy value (empty if it never returned a truthy value).
125
@static
126
*/
127
A.filter = L._isNative(ArrayProto.filter) ?
128
    function(a, f, o) {
129
        return ArrayProto.filter.call(a, f, o);
130
    } :
131
    function(a, f, o) {
132
        var i       = 0,
133
            len     = a.length,
134
            results = [],
135
            item;
136
 
137
        for (; i < len; ++i) {
138
            if (i in a) {
139
                item = a[i];
140
 
141
                if (f.call(o, item, i, a)) {
142
                    results.push(item);
143
                }
144
            }
145
        }
146
 
147
        return results;
148
    };
149
 
150
/**
151
The inverse of `Array.filter()`. Executes the supplied function on each item.
152
Returns a new array containing the items for which the supplied function
153
returned `false`.
154
 
155
@method reject
156
@param {Array} a the array to iterate.
157
@param {Function} f the function to execute on each item.
158
@param {object} [o] Optional context object.
159
@return {Array} The items for which the supplied function returned `false`.
160
@static
161
*/
162
A.reject = function(a, f, o) {
163
    return A.filter(a, function(item, i, a) {
164
        return !f.call(o, item, i, a);
165
    });
166
};
167
 
168
/**
169
Executes the supplied function on each item in the array. Iteration stops if the
170
supplied function does not return a truthy value.
171
 
172
@method every
173
@param {Array} a the array to iterate.
174
@param {Function} f the function to execute on each item.
175
@param {Object} [o] Optional context object.
176
@return {Boolean} `true` if every item in the array returns `true` from the
177
  supplied function, `false` otherwise.
178
@static
179
*/
180
A.every = L._isNative(ArrayProto.every) ?
181
    function(a, f, o) {
182
        return ArrayProto.every.call(a, f, o);
183
    } :
184
    function(a, f, o) {
185
        for (var i = 0, l = a.length; i < l; ++i) {
186
            if (i in a && !f.call(o, a[i], i, a)) {
187
                return false;
188
            }
189
        }
190
 
191
        return true;
192
    };
193
 
194
/**
195
Executes the supplied function on each item in the array and returns a new array
196
containing all the values returned by the supplied function.
197
 
198
@example
199
 
200
    // Convert an array of numbers into an array of strings.
201
    Y.Array.map([1, 2, 3, 4], function (item) {
202
      return '' + item;
203
    });
204
    // => ['1', '2', '3', '4']
205
 
206
@method map
207
@param {Array} a the array to iterate.
208
@param {Function} f the function to execute on each item.
209
@param {object} [o] Optional context object.
210
@return {Array} A new array containing the return value of the supplied function
211
  for each item in the original array.
212
@static
213
*/
214
A.map = L._isNative(ArrayProto.map) ?
215
    function(a, f, o) {
216
        return ArrayProto.map.call(a, f, o);
217
    } :
218
    function(a, f, o) {
219
        var i       = 0,
220
            len     = a.length,
221
            results = ArrayProto.concat.call(a);
222
 
223
        for (; i < len; ++i) {
224
            if (i in a) {
225
                results[i] = f.call(o, a[i], i, a);
226
            }
227
        }
228
 
229
        return results;
230
    };
231
 
232
 
233
/**
234
Executes the supplied function on each item in the array, "folding" the array
235
into a single value.
236
 
237
@method reduce
238
@param {Array} a Array to iterate.
239
@param {Any} init Initial value to start with.
240
@param {Function} f Function to execute on each item. This function should
241
  update and return the value of the computation. It will receive the following
242
  arguments:
243
    @param {Any} f.previousValue Value returned from the previous iteration,
244
      or the initial value if this is the first iteration.
245
    @param {Any} f.currentValue Value of the current item being iterated.
246
    @param {Number} f.index Index of the current item.
247
    @param {Array} f.array Array being iterated.
248
@param {Object} [o] Optional context object.
249
@return {Any} Final result from iteratively applying the given function to each
250
  element in the array.
251
@static
252
*/
253
A.reduce = L._isNative(ArrayProto.reduce) ?
254
    function(a, init, f, o) {
255
        // ES5 Array.reduce doesn't support a thisObject, so we need to
256
        // implement it manually.
257
        return ArrayProto.reduce.call(a, function(init, item, i, a) {
258
            return f.call(o, init, item, i, a);
259
        }, init);
260
    } :
261
    function(a, init, f, o) {
262
        var i      = 0,
263
            len    = a.length,
264
            result = init;
265
 
266
        for (; i < len; ++i) {
267
            if (i in a) {
268
                result = f.call(o, result, a[i], i, a);
269
            }
270
        }
271
 
272
        return result;
273
    };
274
 
275
/**
276
Executes the supplied function on each item in the array, searching for the
277
first item that matches the supplied function.
278
 
279
@method find
280
@param {Array} a the array to search.
281
@param {Function} f the function to execute on each item. Iteration is stopped
282
  as soon as this function returns `true`.
283
@param {Object} [o] Optional context object.
284
@return {Object} the first item that the supplied function returns `true` for,
285
  or `null` if it never returns `true`.
286
@static
287
*/
288
A.find = function(a, f, o) {
289
    for (var i = 0, l = a.length; i < l; i++) {
290
        if (i in a && f.call(o, a[i], i, a)) {
291
            return a[i];
292
        }
293
    }
294
    return null;
295
};
296
 
297
/**
298
Iterates over an array, returning a new array of all the elements that match the
299
supplied regular expression.
300
 
301
@method grep
302
@param {Array} a Array to iterate over.
303
@param {RegExp} pattern Regular expression to test against each item.
304
@return {Array} All the items in the array that produce a match against the
305
  supplied regular expression. If no items match, an empty array is returned.
306
@static
307
*/
308
A.grep = function(a, pattern) {
309
    return A.filter(a, function(item, index) {
310
        return pattern.test(item);
311
    });
312
};
313
 
314
/**
315
Partitions an array into two new arrays, one with the items for which the
316
supplied function returns `true`, and one with the items for which the function
317
returns `false`.
318
 
319
@method partition
320
@param {Array} a Array to iterate over.
321
@param {Function} f Function to execute for each item in the array. It will
322
  receive the following arguments:
323
    @param {Any} f.item Current item.
324
    @param {Number} f.index Index of the current item.
325
    @param {Array} f.array The array being iterated.
326
@param {Object} [o] Optional execution context.
327
@return {Object} An object with two properties: `matches` and `rejects`. Each is
328
  an array containing the items that were selected or rejected by the test
329
  function (or an empty array if none).
330
@static
331
*/
332
A.partition = function(a, f, o) {
333
    var results = {
334
        matches: [],
335
        rejects: []
336
    };
337
 
338
    A.each(a, function(item, index) {
339
        var set = f.call(o, item, index, a) ? results.matches : results.rejects;
340
        set.push(item);
341
    });
342
 
343
    return results;
344
};
345
 
346
/**
347
Creates an array of arrays by pairing the corresponding elements of two arrays
348
together into a new array.
349
 
350
@method zip
351
@param {Array} a Array to iterate over.
352
@param {Array} a2 Another array whose values will be paired with values of the
353
  first array.
354
@return {Array} An array of arrays formed by pairing each element of the first
355
  array with an item in the second array having the corresponding index.
356
@static
357
*/
358
A.zip = function(a, a2) {
359
    var results = [];
360
    A.each(a, function(item, index) {
361
        results.push([item, a2[index]]);
362
    });
363
    return results;
364
};
365
 
366
/**
367
Flattens an array of nested arrays at any abitrary depth into a single, flat
368
array.
369
 
370
@method flatten
371
@param {Array} a Array with nested arrays to flatten.
372
@return {Array} An array whose nested arrays have been flattened.
373
@static
374
@since 3.7.0
375
**/
376
A.flatten = function(a) {
377
    var result = [],
378
        i, len, val;
379
 
380
    // Always return an array.
381
    if (!a) {
382
        return result;
383
    }
384
 
385
    for (i = 0, len = a.length; i < len; ++i) {
386
        val = a[i];
387
 
388
        if (L.isArray(val)) {
389
            // Recusively flattens any nested arrays.
390
            result.push.apply(result, A.flatten(val));
391
        } else {
392
            result.push(val);
393
        }
394
    }
395
 
396
    return result;
397
};
398
 
399
 
400
}, '3.18.1', {"requires": ["yui-base"]});