mirror of
https://github.com/whoisclebs/lodash.git
synced 2026-02-10 19:07:49 +00:00
Add callback and thisArg arguments to _.drop and _.pick. [closes #62]
Former-commit-id: 990655e9e849348c287b3d994d2e2dc741f78fbf
This commit is contained in:
70
lodash.js
70
lodash.js
@@ -483,6 +483,22 @@
|
|||||||
'(hasOwnProperty.call(result, prop) ? result[prop]++ : result[prop] = 1)'
|
'(hasOwnProperty.call(result, prop) ? result[prop]++ : result[prop] = 1)'
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** Reusable iterator options for `drop` and `pick` */
|
||||||
|
var dropIteratorOptions = {
|
||||||
|
'useHas': false,
|
||||||
|
'args': 'object, callback, thisArg',
|
||||||
|
'init': '{}',
|
||||||
|
'top':
|
||||||
|
'var isFunc = typeof callback == \'function\';\n' +
|
||||||
|
'if (!isFunc) {\n' +
|
||||||
|
' var props = concat.apply(ArrayProto, arguments)\n' +
|
||||||
|
'} else if (thisArg) {\n' +
|
||||||
|
' callback = iteratorBind(callback, thisArg)\n' +
|
||||||
|
'}',
|
||||||
|
'inLoop':
|
||||||
|
'if (isFunc ? !callback(value, index, object) : indexOf(props, index) < 0) result[index] = value'
|
||||||
|
};
|
||||||
|
|
||||||
/** Reusable iterator options for `every` and `some` */
|
/** Reusable iterator options for `every` and `some` */
|
||||||
var everyIteratorOptions = {
|
var everyIteratorOptions = {
|
||||||
'init': 'true',
|
'init': 'true',
|
||||||
@@ -1104,7 +1120,9 @@
|
|||||||
/**
|
/**
|
||||||
* Creates a shallow clone of `object` excluding the specified properties.
|
* Creates a shallow clone of `object` excluding the specified properties.
|
||||||
* Property names may be specified as individual arguments or as arrays of
|
* Property names may be specified as individual arguments or as arrays of
|
||||||
* property names.
|
* property names. If `callback` is passed, it will be executed for each property
|
||||||
|
* in the `object`, dropping the properties `callback` returns truthy for. The
|
||||||
|
* `callback` is bound to `thisArg` and invoked with 3 arguments; (value, key, object).
|
||||||
*
|
*
|
||||||
* @static
|
* @static
|
||||||
* @memberOf _
|
* @memberOf _
|
||||||
@@ -1118,13 +1136,7 @@
|
|||||||
* _.drop({ 'name': 'moe', 'age': 40, 'userid': 'moe1' }, 'userid');
|
* _.drop({ 'name': 'moe', 'age': 40, 'userid': 'moe1' }, 'userid');
|
||||||
* // => { 'name': 'moe', 'age': 40 }
|
* // => { 'name': 'moe', 'age': 40 }
|
||||||
*/
|
*/
|
||||||
var drop = createIterator({
|
var drop = createIterator(dropIteratorOptions);
|
||||||
'useHas': false,
|
|
||||||
'args': 'object',
|
|
||||||
'init': '{}',
|
|
||||||
'top': 'var props = concat.apply(ArrayProto, arguments)',
|
|
||||||
'inLoop': 'if (indexOf(props, index) < 0) result[index] = value'
|
|
||||||
});
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Assigns enumerable properties of the source object(s) to the `destination`
|
* Assigns enumerable properties of the source object(s) to the `destination`
|
||||||
@@ -1763,38 +1775,38 @@
|
|||||||
/**
|
/**
|
||||||
* Creates a shallow clone of `object` composed of the specified properties.
|
* Creates a shallow clone of `object` composed of the specified properties.
|
||||||
* Property names may be specified as individual arguments or as arrays of
|
* Property names may be specified as individual arguments or as arrays of
|
||||||
* property names.
|
* property names. If `callback` is passed, it will be executed for each property
|
||||||
|
* in the `object`, picking the properties `callback` returns truthy for. The
|
||||||
|
* `callback` is bound to `thisArg` and invoked with 3 arguments; (value, key, object).
|
||||||
*
|
*
|
||||||
* @static
|
* @static
|
||||||
* @memberOf _
|
* @memberOf _
|
||||||
* @category Objects
|
* @category Objects
|
||||||
* @param {Object} object The source object.
|
* @param {Object} object The source object.
|
||||||
* @param {Object} [prop1, prop2, ...] The properties to pick.
|
* @param {Function|String} [callback|prop1, prop2, ...] The properties to pick
|
||||||
|
* or the function called per iteration.
|
||||||
* @returns {Object} Returns an object composed of the picked properties.
|
* @returns {Object} Returns an object composed of the picked properties.
|
||||||
* @example
|
* @example
|
||||||
*
|
*
|
||||||
* _.pick({ 'name': 'moe', 'age': 40, 'userid': 'moe1' }, 'name', 'age');
|
* _.pick({ 'name': 'moe', 'age': 40, 'userid': 'moe1' }, 'name', 'age');
|
||||||
* // => { 'name': 'moe', 'age': 40 }
|
* // => { 'name': 'moe', 'age': 40 }
|
||||||
*/
|
*/
|
||||||
function pick(object) {
|
var pick = createIterator(dropIteratorOptions, {
|
||||||
var result = {};
|
'top':
|
||||||
if (!object) {
|
'if (typeof callback != \'function\') {\n' +
|
||||||
return result;
|
' var prop,\n' +
|
||||||
}
|
' props = concat.apply(ArrayProto, arguments),\n' +
|
||||||
var prop,
|
' length = props.length;\n' +
|
||||||
index = 0,
|
' for (index = 1; index < length; index++) {\n' +
|
||||||
props = concat.apply(ArrayProto, arguments),
|
' prop = props[index];\n' +
|
||||||
length = props.length;
|
' if (prop in object) result[prop] = object[prop]\n' +
|
||||||
|
' }\n' +
|
||||||
// start `index` at `1` to skip `object`
|
'} else {\n' +
|
||||||
while (++index < length) {
|
' if (thisArg) callback = iteratorBind(callback, thisArg)',
|
||||||
prop = props[index];
|
'inLoop':
|
||||||
if (prop in object) {
|
'if (callback(value, index, object)) result[index] = value',
|
||||||
result[prop] = object[prop];
|
'bottom': '}'
|
||||||
}
|
});
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the size of `value` by returning `value.length` if `value` is an
|
* Gets the size of `value` by returning `value.length` if `value` is an
|
||||||
|
|||||||
72
test/test.js
72
test/test.js
@@ -336,11 +336,11 @@
|
|||||||
QUnit.module('lodash.drop');
|
QUnit.module('lodash.drop');
|
||||||
|
|
||||||
(function() {
|
(function() {
|
||||||
var object = { 'a': 1, 'b': 2, 'c': 3 },
|
var object = { 'a': 1, 'b': 2 },
|
||||||
actual = { 'b': 2 };
|
actual = { 'b': 2 };
|
||||||
|
|
||||||
test('should accept individual property names', function() {
|
test('should accept individual property names', function() {
|
||||||
deepEqual(_.drop(object, 'a', 'c'), actual);
|
deepEqual(_.drop(object, 'a'), actual);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should accept an array of property names', function() {
|
test('should accept an array of property names', function() {
|
||||||
@@ -355,7 +355,38 @@
|
|||||||
function Foo() {}
|
function Foo() {}
|
||||||
Foo.prototype = object;
|
Foo.prototype = object;
|
||||||
|
|
||||||
deepEqual(_.drop(new Foo, 'a', 'c'), actual);
|
deepEqual(_.drop(new Foo, 'a'), actual);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should work with a `callback` argument', function() {
|
||||||
|
var actual = _.drop(object, function(value) {
|
||||||
|
return value == 1;
|
||||||
|
});
|
||||||
|
|
||||||
|
deepEqual(actual, { 'b': 2 });
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should pass the correct `callback` arguments', function() {
|
||||||
|
var args,
|
||||||
|
lastKey = _.keys(object).pop();
|
||||||
|
|
||||||
|
var expected = lastKey == 'b'
|
||||||
|
? [1, 'a', object]
|
||||||
|
: [2, 'b', object];
|
||||||
|
|
||||||
|
_.drop(object, function() {
|
||||||
|
args || (args = slice.call(arguments));
|
||||||
|
});
|
||||||
|
|
||||||
|
deepEqual(args, expected);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should correct set the `this` binding', function() {
|
||||||
|
var actual = _.drop(object, function(value) {
|
||||||
|
return value == this.a;
|
||||||
|
}, { 'a': 1 });
|
||||||
|
|
||||||
|
deepEqual(actual, { 'b': 2 });
|
||||||
});
|
});
|
||||||
}());
|
}());
|
||||||
|
|
||||||
@@ -1070,12 +1101,45 @@
|
|||||||
QUnit.module('lodash.pick');
|
QUnit.module('lodash.pick');
|
||||||
|
|
||||||
(function() {
|
(function() {
|
||||||
|
var object = { 'a': 1, 'b': 2 };
|
||||||
|
|
||||||
test('should iterate over inherited properties', function() {
|
test('should iterate over inherited properties', function() {
|
||||||
function Foo() {}
|
function Foo() {}
|
||||||
Foo.prototype = { 'a': 1, 'b': 2, 'c': 3 };
|
Foo.prototype = object;
|
||||||
|
|
||||||
deepEqual(_.pick(new Foo, 'b'), { 'b': 2 });
|
deepEqual(_.pick(new Foo, 'b'), { 'b': 2 });
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('should work with a `callback` argument', function() {
|
||||||
|
var actual = _.pick(object, function(value) {
|
||||||
|
return value == 2;
|
||||||
|
});
|
||||||
|
|
||||||
|
deepEqual(actual, { 'b': 2 });
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should pass the correct `callback` arguments', function() {
|
||||||
|
var args,
|
||||||
|
lastKey = _.keys(object).pop();
|
||||||
|
|
||||||
|
var expected = lastKey == 'b'
|
||||||
|
? [1, 'a', object]
|
||||||
|
: [2, 'b', object];
|
||||||
|
|
||||||
|
_.pick(object, function() {
|
||||||
|
args || (args = slice.call(arguments));
|
||||||
|
});
|
||||||
|
|
||||||
|
deepEqual(args, expected);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should correct set the `this` binding', function() {
|
||||||
|
var actual = _.pick(object, function(value) {
|
||||||
|
return value == this.b;
|
||||||
|
}, { 'b': 2 });
|
||||||
|
|
||||||
|
deepEqual(actual, { 'b': 2 });
|
||||||
|
});
|
||||||
}());
|
}());
|
||||||
|
|
||||||
/*--------------------------------------------------------------------------*/
|
/*--------------------------------------------------------------------------*/
|
||||||
|
|||||||
Reference in New Issue
Block a user