mirror of
https://github.com/whoisclebs/lodash.git
synced 2026-01-31 15:27:50 +00:00
Move _.pluck and _.invoke back to the "Collections" category and optimize _.sortedIndex when a callback is passed.
Former-commit-id: d16763e7d35660d8ba9ea976c8b2a4dc20f1211f
This commit is contained in:
@@ -8,6 +8,7 @@
|
||||
/** Used to minify variables embedded in compiled strings */
|
||||
var compiledVars = [
|
||||
'accumulator',
|
||||
'args',
|
||||
'arrayClass',
|
||||
'callback',
|
||||
'className',
|
||||
@@ -18,14 +19,17 @@
|
||||
'hasOwnProperty',
|
||||
'identity',
|
||||
'index',
|
||||
'isFunc',
|
||||
'iteratorBind',
|
||||
'length',
|
||||
'methodName',
|
||||
'noaccum',
|
||||
'object',
|
||||
'objectTypes',
|
||||
'noaccum',
|
||||
'property',
|
||||
'result',
|
||||
'skipProto',
|
||||
'slice',
|
||||
'source',
|
||||
'sourceIndex',
|
||||
'stringClass',
|
||||
|
||||
169
lodash.js
169
lodash.js
@@ -339,6 +339,20 @@
|
||||
}
|
||||
};
|
||||
|
||||
/** Reusable iterator options for `invoke`, `map`, and `pluck` */
|
||||
var mapIteratorOptions = {
|
||||
'init': '',
|
||||
'exit': 'if (!collection) return []',
|
||||
'beforeLoop': {
|
||||
'array': 'result = Array(length)',
|
||||
'object': 'result = []'
|
||||
},
|
||||
'inLoop': {
|
||||
'array': 'result[index] = callback(collection[index], index, collection)',
|
||||
'object': 'result.push(callback(collection[index], index, collection))'
|
||||
}
|
||||
};
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
@@ -437,13 +451,13 @@
|
||||
// create the function factory
|
||||
var factory = Function(
|
||||
'arrayClass, funcClass, hasOwnProperty, identity, iteratorBind, objectTypes, ' +
|
||||
'stringClass, toString, undefined',
|
||||
'slice, stringClass, toString, undefined',
|
||||
'"use strict"; return function(' + args + ') {\n' + iteratorTemplate(data) + '\n}'
|
||||
);
|
||||
// return the compiled function
|
||||
return factory(
|
||||
arrayClass, funcClass, hasOwnProperty, identity, iteratorBind, objectTypes,
|
||||
stringClass, toString
|
||||
slice, stringClass, toString
|
||||
);
|
||||
}
|
||||
|
||||
@@ -679,7 +693,40 @@
|
||||
var forEach = createIterator(baseIteratorOptions, forEachIteratorOptions);
|
||||
|
||||
/**
|
||||
* Produces a new array of values by mapping each value in the `collection`
|
||||
* Invokes the method named by `methodName` on each element in the `collection`.
|
||||
* Additional arguments will be passed to each invoked method. If `methodName`
|
||||
* is a function it will be invoked for, and `this` bound to, each element
|
||||
* in the `collection`.
|
||||
*
|
||||
* @static
|
||||
* @memberOf _
|
||||
* @category Collections
|
||||
* @param {Array|Object} collection The collection to iterate over.
|
||||
* @param {Function|String} methodName The name of the method to invoke or
|
||||
* the function invoked per iteration.
|
||||
* @param {Mixed} [arg1, arg2, ...] Arguments to invoke the method with.
|
||||
* @returns {Array} Returns a new array of values returned from each invoked method.
|
||||
* @example
|
||||
*
|
||||
* _.invoke([[5, 1, 7], [3, 2, 1]], 'sort');
|
||||
* // => [[1, 5, 7], [1, 2, 3]]
|
||||
*
|
||||
* _.invoke([123, 456], String.prototype.split, '');
|
||||
* // => [['1', '2', '3'], ['4', '5', '6']]
|
||||
*/
|
||||
var invoke = createIterator(mapIteratorOptions, {
|
||||
'args': 'collection, methodName',
|
||||
'top':
|
||||
'var args = slice.call(arguments, 2),\n' +
|
||||
' isFunc = typeof methodName == \'function\'',
|
||||
'inLoop': {
|
||||
'array': 'result[index] = (isFunc ? methodName : collection[index][methodName]).apply(collection[index], args)',
|
||||
'object': 'result.push((isFunc ? methodName : collection[index][methodName]).apply(collection[index], args))'
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Produces a new array of values by mapping each element in the `collection`
|
||||
* through a transformation `callback`. The `callback` is bound to `thisArg`
|
||||
* and invoked with 3 arguments; for arrays they are (value, index, array)
|
||||
* and for objects they are (value, key, object).
|
||||
@@ -700,16 +747,34 @@
|
||||
* _.map({ 'one': 1, 'two': 2, 'three': 3 }, function(num) { return num * 3; });
|
||||
* // => [3, 6, 9] (order is not guaranteed)
|
||||
*/
|
||||
var map = createIterator(baseIteratorOptions, {
|
||||
'init': '',
|
||||
'exit': 'if (!collection) return []',
|
||||
'beforeLoop': {
|
||||
'array': 'result = Array(length)',
|
||||
'object': 'result = []'
|
||||
},
|
||||
var map = createIterator(baseIteratorOptions, mapIteratorOptions);
|
||||
|
||||
/**
|
||||
* Retrieves the value of a specified property from all elements in
|
||||
* the `collection`.
|
||||
*
|
||||
* @static
|
||||
* @memberOf _
|
||||
* @category Collections
|
||||
* @param {Array|Object} collection The collection to iterate over.
|
||||
* @param {String} property The property to pluck.
|
||||
* @returns {Array} Returns a new array of property values.
|
||||
* @example
|
||||
*
|
||||
* var stooges = [
|
||||
* { 'name': 'moe', 'age': 40 },
|
||||
* { 'name': 'larry', 'age': 50 },
|
||||
* { 'name': 'curly', 'age': 60 }
|
||||
* ];
|
||||
*
|
||||
* _.pluck(stooges, 'name');
|
||||
* // => ['moe', 'larry', 'curly']
|
||||
*/
|
||||
var pluck = createIterator(mapIteratorOptions, {
|
||||
'args': 'collection, property',
|
||||
'inLoop': {
|
||||
'array': 'result[index] = callback(collection[index], index, collection)',
|
||||
'object': 'result.push(callback(collection[index], index, collection))'
|
||||
'array': 'result[index] = collection[index][property]',
|
||||
'object': 'result.push(collection[index][property])'
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1159,44 +1224,6 @@
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Invokes the method named by `methodName` on each element of `array`.
|
||||
* Additional arguments will be passed to each invoked method. If `methodName`
|
||||
* is a function it will be invoked for, and `this` bound to, each element
|
||||
* of `array`.
|
||||
*
|
||||
* @static
|
||||
* @memberOf _
|
||||
* @category Arrays
|
||||
* @param {Array} array The array to iterate over.
|
||||
* @param {Function|String} methodName The name of the method to invoke or
|
||||
* the function invoked per iteration.
|
||||
* @param {Mixed} [arg1, arg2, ...] Arguments to invoke the method with.
|
||||
* @returns {Array} Returns a new array of values returned from each invoked method.
|
||||
* @example
|
||||
*
|
||||
* _.invoke([[5, 1, 7], [3, 2, 1]], 'sort');
|
||||
* // => [[1, 5, 7], [1, 2, 3]]
|
||||
*
|
||||
* _.invoke([123, 456], String.prototype.split, '');
|
||||
* // => [['1', '2', '3'], ['4', '5', '6']]
|
||||
*/
|
||||
function invoke(array, methodName) {
|
||||
var result = [];
|
||||
if (!array) {
|
||||
return result;
|
||||
}
|
||||
var args = slice.call(arguments, 2),
|
||||
index = -1,
|
||||
length = array.length,
|
||||
isFunc = typeof methodName == 'function';
|
||||
|
||||
while (++index < length) {
|
||||
result[index] = (isFunc ? methodName : array[index][methodName]).apply(array[index], args);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the last value of the `array`. Pass `n` to return the lasy `n` values
|
||||
* of the `array`.
|
||||
@@ -1363,40 +1390,6 @@
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the value of a specified property from all elements in `array`.
|
||||
*
|
||||
* @static
|
||||
* @memberOf _
|
||||
* @category Arrays
|
||||
* @param {Array} array The array to iterate over.
|
||||
* @param {String} property The property to pluck.
|
||||
* @returns {Array} Returns a new array of property values.
|
||||
* @example
|
||||
*
|
||||
* var stooges = [
|
||||
* { 'name': 'moe', 'age': 40 },
|
||||
* { 'name': 'larry', 'age': 50 },
|
||||
* { 'name': 'curly', 'age': 60 }
|
||||
* ];
|
||||
*
|
||||
* _.pluck(stooges, 'name');
|
||||
* // => ['moe', 'larry', 'curly']
|
||||
*/
|
||||
function pluck(array, property) {
|
||||
if (!array) {
|
||||
return [];
|
||||
}
|
||||
var index = -1,
|
||||
length = array.length,
|
||||
result = Array(length);
|
||||
|
||||
while (++index < length) {
|
||||
result[index] = array[index][property];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an array of numbers (positive and/or negative) progressing from
|
||||
* `start` up to but not including `stop`. This method is a port of Python's
|
||||
@@ -1608,10 +1601,14 @@
|
||||
high = array.length;
|
||||
|
||||
if (callback) {
|
||||
value = callback.call(thisArg, value);
|
||||
if (thisArg) {
|
||||
var fn = callback;
|
||||
callback = function(value) { return fn.call(thisArg, value); };
|
||||
}
|
||||
value = callback(value);
|
||||
while (low < high) {
|
||||
mid = (low + high) >>> 1;
|
||||
callback.call(thisArg, array[mid]) < value ? low = mid + 1 : high = mid;
|
||||
callback(array[mid]) < value ? low = mid + 1 : high = mid;
|
||||
}
|
||||
} else {
|
||||
while (low < high) {
|
||||
|
||||
26
test/test.js
26
test/test.js
@@ -378,6 +378,17 @@
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
QUnit.module('lodash.invoke');
|
||||
|
||||
(function() {
|
||||
test('should work with an object for `collection`', function() {
|
||||
var object = { 'a': 1, 'b': 2, 'c': 3 };
|
||||
deepEqual(_.invoke(object, 'toFixed', 1), ['1.0', '2.0', '3.0']);
|
||||
});
|
||||
}());
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
QUnit.module('lodash.isEmpty');
|
||||
|
||||
(function() {
|
||||
@@ -520,6 +531,17 @@
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
QUnit.module('lodash.pluck');
|
||||
|
||||
(function() {
|
||||
test('should work with an object for `collection`', function() {
|
||||
var object = { 'a': [1], 'b': [1, 2], 'c': [1, 2, 3] };
|
||||
deepEqual(_.pluck(object, 'length'), [1, 2, 3]);
|
||||
});
|
||||
}());
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
QUnit.module('lodash.reduceRight');
|
||||
|
||||
(function() {
|
||||
@@ -743,12 +765,10 @@
|
||||
'indexOf',
|
||||
'initial',
|
||||
'intersection',
|
||||
'invoke',
|
||||
'last',
|
||||
'lastIndexOf',
|
||||
'max',
|
||||
'min',
|
||||
'pluck',
|
||||
'range',
|
||||
'rest',
|
||||
'shuffle',
|
||||
@@ -782,7 +802,9 @@
|
||||
'filter',
|
||||
'find',
|
||||
'forEach',
|
||||
'invoke',
|
||||
'map',
|
||||
'pluck',
|
||||
'reduce',
|
||||
'reduceRight',
|
||||
'reject',
|
||||
|
||||
Reference in New Issue
Block a user