diff --git a/build.js b/build.js index 6762c34ae..3fd4a98dc 100755 --- a/build.js +++ b/build.js @@ -156,7 +156,7 @@ 'uniqueId': [], 'value': ['mixin'], 'values': ['forOwn'], - 'where': ['filter', 'forIn'], + 'where': ['filter', 'keys'], 'without': ['indexOf'], 'wrap': [], 'zip': ['max', 'pluck'] @@ -988,13 +988,14 @@ dependencyMap.reduceRight = ['forEach', 'keys']; } if (isUnderscore) { - dependencyMap.contains = ['forEach', 'indexOf'], + dependencyMap.contains = ['forEach', 'indexOf']; dependencyMap.isEqual = ['isArray', 'isFunction']; dependencyMap.isEmpty = ['isArray', 'isString']; dependencyMap.max = ['forEach', 'isArray']; dependencyMap.min = ['forEach', 'isArray']; dependencyMap.pick = []; dependencyMap.template = ['defaults', 'escape']; + dependencyMap.where = ['filter', 'forIn']; if (useUnderscoreClone) { dependencyMap.clone = ['assign', 'isArray']; @@ -1255,6 +1256,26 @@ ' }' ].join('\n')); + // replace `_.where` + source = source.replace(/^( *)function where[\s\S]+?\n\1}/m, [ + ' function where(collection, properties) {', + ' var props = [];', + ' forIn(properties, function(value, prop) {', + ' props.push(prop);', + ' });', + ' return filter(collection, function(object) {', + ' var length = props.length;', + ' while (length--) {', + ' var result = object[props[length]] === properties[props[length]];', + ' if (!result) {', + ' break;', + ' }', + ' }', + ' return !!result;', + ' });', + ' }' + ].join('\n')); + // replace `_.without` source = source.replace(/^( *)function without[\s\S]+?\n\1}/m, [ ' function without(array) {', diff --git a/lodash.js b/lodash.js index bf77e89ec..5d785f3d4 100644 --- a/lodash.js +++ b/lodash.js @@ -2537,10 +2537,7 @@ * // => [{ 'name': 'moe', 'age': 40 }] */ function where(collection, properties) { - var props = []; - forIn(properties, function(value, prop) { - props.push(prop); - }); + var props = keys(properties); return filter(collection, function(object) { var length = props.length; while (length--) { diff --git a/test/test-build.js b/test/test-build.js index d090c9b58..d961097dc 100644 --- a/test/test-build.js +++ b/test/test-build.js @@ -636,7 +636,7 @@ build(['-s', 'underscore'], function(source, filePath) { var last, - array = [{ 'value': 1 }, { 'value': 2 }], + array = [{ 'a': 1, 'b': 2 }, { 'a': 2, 'b': 2 }], basename = path.basename(filePath, '.js'), context = createContext(); @@ -658,17 +658,17 @@ deepEqual(lodash.extend({}, new Foo), Foo.prototype, '_.extend should assign inherited `source` properties: ' + basename); actual = lodash.find(array, function(value) { - return 'value' in value; + return 'a' in value; }); - equal(actual, array[0], '_.find: ' + basename); + equal(actual, _.first(array), '_.find: ' + basename); actual = lodash.forEach(array, function(value) { last = value; return false; }); - equal(last.value, 2, '_.forEach should not exit early: ' + basename); + equal(last, _.last(array), '_.forEach should not exit early: ' + basename); equal(actual, undefined, '_.forEach should return `undefined`: ' + basename); object = { 'length': 0, 'splice': Array.prototype.splice }; @@ -688,6 +688,11 @@ equal(lodash.some([false, true, false]), true, '_.some: ' + basename); equal(lodash.template('${a}', object), '${a}', '_.template should ignore ES6 delimiters: ' + basename); + + var properties = new Foo; + properties.b = 2; + deepEqual(lodash.where(array, properties), [_.first(array)], '_.where should filter by inherited properties: ' + basename); + start(); }); }); diff --git a/test/test.js b/test/test.js index a651a8662..5ad0e5d23 100644 --- a/test/test.js +++ b/test/test.js @@ -1855,14 +1855,13 @@ deepEqual(_.where(array, { 'a': 1, 'b': 2 }), [{ 'a': 1, 'b': 2 }]); }); - test('should filter by inherited properties', function() { + test('should not filter by inherited properties', function() { function Foo() {} - Foo.prototype = { 'b': 2 }; + Foo.prototype = { 'a': 2 }; var properties = new Foo; - properties.a = 1; - - deepEqual(_.where(array, properties), [{ 'a': 1, 'b': 2 }]); + properties.b = 2; + deepEqual(_.where(array, properties), [{ 'a': 1, 'b': 2 }, { 'a': 2, 'b': 2 }]); }); test('should filter by problem JScript properties (test in IE < 9)', function() {