Add _.where. [closes #22].

Former-commit-id: dec7a9d0df4158a395ec84fb9e774ed20205d421
This commit is contained in:
John-David Dalton
2012-07-29 13:48:21 -07:00
parent 86bd847bf9
commit 80d0b5d4ed
3 changed files with 65 additions and 16 deletions

View File

@@ -231,6 +231,7 @@
'uniq': ['identity', 'indexOf'],
'uniqueId': [],
'values': [],
'where': ['forIn'],
'without': ['indexOf'],
'wrap': [],
'zip': ['max', 'pluck'],
@@ -270,6 +271,7 @@
'forIn',
'forOwn',
'partial',
'where',
'zipObject'
]));
@@ -338,6 +340,17 @@
return realToAliasMap[funcName] || [];
}
/**
* Gets the Lo-Dash method assignments snippet from `source`.
*
* @private
* @param {String} source The source to inspect.
* @returns {String} Returns the method assignments snippet.
*/
function getMethodAssignments(source) {
return (source.match(/lodash\.VERSION *= *[\s\S]+?\/\*-+\*\/\n/) || [''])[0];
}
/**
* Gets an array of depenants for a function by a given name.
*
@@ -502,7 +515,7 @@
source = source.replace(matchFunction(source, funcName), '');
// grab the method assignments snippet
snippet = source.match(/lodash\.VERSION *= *[\s\S]+?\/\*-+\*\/\n/)[0];
snippet = getMethodAssignments(source);
// remove assignment and aliases
modified = getAliases(funcName).concat(funcName).reduce(function(result, otherName) {
@@ -771,10 +784,8 @@
if (!iteratorName) {
return;
}
var snippet,
funcNames = [],
objectSnippets = [],
token = '__isTypeToken__';
var funcNames = [],
objectSnippets = [];
// build replacement code
lodash.forOwn({
@@ -788,10 +799,6 @@
funcCode = matchFunction(source, funcName);
if (funcCode) {
if (!snippet) {
// use snippet to mark the insert position
snippet = funcCode;
}
funcNames.push(funcName);
objectSnippets.push("'" + key + "': " + value);
}
@@ -801,22 +808,21 @@
if (funcNames.length < 2) {
return;
}
// add a token to mark the position to insert new code
source = source.replace(snippet, '\n' + token + '\n' + snippet);
// remove existing isType functions
funcNames.forEach(function(funcName) {
source = removeFunction(source, funcName);
});
// replace token with new DRY code
source = source.replace(token,
// insert new DRY code after the method assignments
var snippet = getMethodAssignments(source);
source = source.replace(snippet, snippet + '\n' +
' // add `_.' + funcNames.join('`, `_.') + '`\n' +
' ' + iteratorName + '({\n ' + objectSnippets.join(',\n ') + '\n }, function(className, key) {\n' +
" lodash['is' + key] = function(value) {\n" +
' return toString.call(value) == className;\n' +
' };\n' +
' });'
' });\n'
);
}());

View File

@@ -18,6 +18,7 @@
'compareAscending',
'concat',
'ctor',
'forIn',
'funcClass',
'funcs',
'hasOwnProperty',
@@ -35,11 +36,16 @@
'noaccum',
'object',
'objectTypes',
'ownIndex',
'ownProps',
'pass',
'prop',
'propIndex',
'props',
'properties',
'property',
'propertyIsEnumerable',
'propIndex',
'props',
'propsLength',
'result',
'skipProto',
'slice',
@@ -195,6 +201,7 @@
'values',
'variable',
'VERSION',
'where',
'without',
'wrap',
'zip',

View File

@@ -1277,6 +1277,41 @@
return values(collection);
}
/**
* Examines each element in a `collection`, returning an array of all elements
* that contain the given `properties`.
*
* @static
* @memberOf _
* @category Collections
* @param {Array|Object|String} collection The collection to iterate over.
* @param {Object} properties The object of properties/values to filter by.
* @returns {Array} Returns a new array of elements that contain the given `properties`.
* @example
*
* var stooges = [
* { 'name': 'moe', 'age': 40 },
* { 'name': 'larry', 'age': 50 },
* { 'name': 'curly', 'age': 60 }
* ];
*
* _.where(stooges, { 'age': 40 });
* // => [{ 'name': 'moe', 'age': 40 }]
*/
var where = createIterator(filterIteratorOptions, {
'args': 'collection, properties',
'top':
'var pass, prop, propIndex, props = [];\n' +
'forIn(properties, function(value, prop) { props.push(prop) });\n' +
'var propsLength = props.length',
'inLoop':
'for (pass = true, propIndex = 0; propIndex < propsLength; propIndex++) {\n' +
' prop = props[propIndex];\n' +
' if (pass = value[prop] === properties[prop]) break\n' +
'}\n' +
'if (pass) result.push(value)'
});
/*--------------------------------------------------------------------------*/
/**
@@ -3920,6 +3955,7 @@
lodash.uniq = uniq;
lodash.uniqueId = uniqueId;
lodash.values = values;
lodash.where = where;
lodash.without = without;
lodash.wrap = wrap;
lodash.zip = zip;