From 3988a671b5e3aafbda3192ea0488e4ba00f10a0b Mon Sep 17 00:00:00 2001 From: Justin Ridgewell Date: Fri, 3 Apr 2015 14:44:36 -0400 Subject: [PATCH] Combine _.min and _.max http://jsperf.com/min-max-code-sharing --- underscore.js | 64 ++++++++++++++++----------------------------------- 1 file changed, 20 insertions(+), 44 deletions(-) diff --git a/underscore.js b/underscore.js index b38b1192b..975c8ca0d 100644 --- a/underscore.js +++ b/underscore.js @@ -277,56 +277,32 @@ return _.find(obj, _.matcher(attrs)); }; - // Return the maximum element (or element-based computation). - _.max = function(obj, iteratee, context) { - var result = -Infinity, lastComputed = -Infinity, - value, computed; - if (iteratee == null && obj != null) { - obj = isArrayLike(obj) ? obj : _.values(obj); - for (var i = 0, length = obj.length; i < length; i++) { - value = obj[i]; - if (value > result) { - result = value; - } - } - } else { - iteratee = cb(iteratee, context); - _.each(obj, function(value, index, list) { - computed = iteratee(value, index, list); - if (computed > lastComputed || computed === -Infinity && result === -Infinity) { + // Generator function to create the max and min functions + var createExtremumFinder = function(dir) { + return function(obj, iteratee, context) { + var keys = !isArrayLike(obj) && _.keys(obj), + length = (keys || obj).length, + result = dir * Infinity, + lastComputed = result, + index = 0, currentKey, value; + if (iteratee != null) iteratee = cb(iteratee, context); + for (; index < length; index++) { + currentKey = keys ? keys[index] : index; + value = obj[currentKey]; + var computed = iteratee ? iteratee(value, currentKey, obj) : value; + if ((dir < 0 ? computed > lastComputed : computed < lastComputed) || index === 0 && computed === lastComputed) { result = value; lastComputed = computed; } - }); - } - return result; - }; - - // Return the minimum element (or element-based computation). - _.min = function(obj, iteratee, context) { - var result = Infinity, lastComputed = Infinity, - value, computed; - if (iteratee == null && obj != null) { - obj = isArrayLike(obj) ? obj : _.values(obj); - for (var i = 0, length = obj.length; i < length; i++) { - value = obj[i]; - if (value < result) { - result = value; - } } - } else { - iteratee = cb(iteratee, context); - _.each(obj, function(value, index, list) { - computed = iteratee(value, index, list); - if (computed < lastComputed || computed === Infinity && result === Infinity) { - result = value; - lastComputed = computed; - } - }); - } - return result; + return result; + }; }; + // Return the extremum element (or element-based computation). + _.max = createExtremumFinder(-1); + _.min = createExtremumFinder(1); + // Shuffle a collection, using the modern version of the // [Fisher-Yates shuffle](http://en.wikipedia.org/wiki/Fisher–Yates_shuffle). _.shuffle = function(obj) {