From 07434b19aef2e44210fda50a4fe938556b83e55b Mon Sep 17 00:00:00 2001 From: John-David Dalton Date: Sat, 15 Mar 2014 03:41:31 -0700 Subject: [PATCH] Ensure find methods work with strings. --- lodash.js | 41 +++++++++++++++++-------- test/test.js | 84 +++++++++++++++++++++++++++++++++++----------------- 2 files changed, 85 insertions(+), 40 deletions(-) diff --git a/lodash.js b/lodash.js index 2b49fa82c..0d095f1be 100644 --- a/lodash.js +++ b/lodash.js @@ -3797,14 +3797,27 @@ * // => { 'name': 'fred', 'age': 40, 'blocked': true } */ function find(collection, predicate, thisArg) { - var length = collection ? collection.length : 0; + predicate = lodash.createCallback(predicate, thisArg, 3); + if (isArray(collection)) { + var index = -1, + length = collection.length; - if (typeof length == 'number' && length > -1 && length <= maxSafeInteger) { - var index = findIndex(collection, predicate, thisArg); - return index > -1 ? collection[index] : undefined; + while (++index < length) { + var value = collection[index]; + if (predicate(value, index, collection)) { + return value; + } + } + } else { + var result; + baseEach(collection, function(value, index, collection) { + if (predicate(value, index, collection)) { + result = value; + return false; + } + }); + return result; } - var key = findKey(collection, predicate, thisArg); - return typeof key == 'string' ? collection[key] : undefined; } /** @@ -3828,14 +3841,16 @@ * // => 3 */ function findLast(collection, predicate, thisArg) { - var length = collection ? collection.length : 0; + var result; - if (typeof length == 'number' && length > -1 && length <= maxSafeInteger) { - var index = findLastIndex(collection, predicate, thisArg); - return index > -1 ? collection[index] : undefined; - } - var key = findLastKey(collection, predicate, thisArg); - return typeof key == 'string' ? collection[key] : undefined; + predicate = lodash.createCallback(predicate, thisArg, 3); + baseEachRight(collection, function(value, index, collection) { + if (predicate(value, index, collection)) { + result = value; + return false; + } + }); + return result; } /** diff --git a/test/test.js b/test/test.js index 222a66a50..9fc389793 100644 --- a/test/test.js +++ b/test/test.js @@ -2393,25 +2393,26 @@ /*--------------------------------------------------------------------------*/ - (function() { - var objects = [ - { 'a': 0, 'b': 0 }, - { 'a': 1, 'b': 1 }, - { 'a': 2, 'b': 2 } - ]; + _.forEach(['find', 'findLast', 'findIndex', 'findLastIndex', 'findKey', 'findLastKey'], function(methodName) { + QUnit.module('lodash.' + methodName); - _.forEach({ - 'find': [objects[1], undefined, objects[2], objects[1]], - 'findLast': [objects[2], undefined, objects[2], objects[2]], - 'findIndex': [1, -1, 2, 1], - 'findLastIndex': [2, -1, 2, 2], - 'findKey': ['1', undefined, '2', '1'], - 'findLastKey': ['2', undefined, '2', '2'] - }, - function(expected, methodName) { - QUnit.module('lodash.' + methodName); + var func = _[methodName]; - var func = _[methodName]; + (function() { + var objects = [ + { 'a': 0, 'b': 0 }, + { 'a': 1, 'b': 1 }, + { 'a': 2, 'b': 2 } + ]; + + var expected = ({ + 'find': [objects[1], undefined, objects[2], objects[1]], + 'findLast': [objects[2], undefined, objects[2], objects[2]], + 'findIndex': [1, -1, 2, 1], + 'findLastIndex': [2, -1, 2, 2], + 'findKey': ['1', undefined, '2', '1'], + 'findLastKey': ['2', undefined, '2', '2'] + })[methodName]; test('should return the correct value', 1, function() { strictEqual(func(objects, function(object) { return object.a; }), expected[0]); @@ -2425,14 +2426,6 @@ strictEqual(func(objects, function(object) { return object.a == 3; }), expected[1]); }); - test('should work with an object for `collection`', 1, function() { - var actual = _.find({ 'a': 1, 'b': 2, 'c': 3 }, function(num) { - return num > 2; - }); - - equal(actual, 3); - }); - test('should work with an object for `callback`', 1, function() { strictEqual(func(objects, { 'b': 2 }), expected[2]); }); @@ -2454,15 +2447,52 @@ deepEqual(actual, expecting); }); + }()); + (function() { + var expected = ({ + 'find': 1, + 'findLast': 2, + 'findKey': 'a', + 'findLastKey': 'b' + })[methodName]; + + if (expected != null) { + test('should work with an object for `collection`', 1, function() { + var actual = func({ 'a': 1, 'b': 2, 'c': 3 }, function(num) { + return num < 3; + }); + + equal(actual, expected); + }); + } + }()); + + (function() { + var expected = ({ + 'find': 'a', + 'findLast': 'b', + 'findIndex': 0, + 'findLastIndex': 1 + })[methodName]; + + if (expected != null) { + test('should work with a string for `collection`', 1, function() { + var actual = func('abc', function(chr, index) { + return index < 2; + }); + + equal(actual, expected); + }); + } if (methodName == 'find') { test('should be aliased', 2, function() { strictEqual(_.detect, func); strictEqual(_.findWhere, func); }); } - }); - }()); + }()); + }); /*--------------------------------------------------------------------------*/