|
277 | 277 | return _.find(obj, _.matcher(attrs)); |
278 | 278 | }; |
279 | 279 |
|
280 | | - // Return the maximum element (or element-based computation). |
281 | | - _.max = function(obj, iteratee, context) { |
282 | | - var result = -Infinity, lastComputed = -Infinity, |
283 | | - value, computed; |
284 | | - if (iteratee == null && obj != null) { |
285 | | - obj = isArrayLike(obj) ? obj : _.values(obj); |
286 | | - for (var i = 0, length = obj.length; i < length; i++) { |
287 | | - value = obj[i]; |
288 | | - if (value > result) { |
289 | | - result = value; |
290 | | - } |
291 | | - } |
292 | | - } else { |
| 280 | + // Generator function to create the max and min functions |
| 281 | + var createExtremumFinder = function(max) { |
| 282 | + return function(obj, iteratee, context) { |
| 283 | + var keys = !isArrayLike(obj) && _.keys(obj), |
| 284 | + length = (keys || obj).length, |
| 285 | + result = max ? -Infinity : Infinity, |
| 286 | + lastComputed = result, |
| 287 | + found = false; |
293 | 288 | iteratee = cb(iteratee, context); |
294 | | - _.each(obj, function(value, index, list) { |
295 | | - computed = iteratee(value, index, list); |
296 | | - if (computed > lastComputed || computed === -Infinity && result === -Infinity) { |
| 289 | + for (var index = 0; index < length; index++) { |
| 290 | + var currentKey = keys ? keys[index] : index; |
| 291 | + var value = obj[currentKey]; |
| 292 | + var computed = iteratee ? iteratee(value, currentKey, obj) : value; |
| 293 | + if ((max ? computed > lastComputed : computed < lastComputed) || (!found && computed === result)) { |
| 294 | + found = true; |
297 | 295 | result = value; |
298 | 296 | lastComputed = computed; |
299 | 297 | } |
300 | | - }); |
301 | | - } |
302 | | - return result; |
303 | | - }; |
304 | | - |
305 | | - // Return the minimum element (or element-based computation). |
306 | | - _.min = function(obj, iteratee, context) { |
307 | | - var result = Infinity, lastComputed = Infinity, |
308 | | - value, computed; |
309 | | - if (iteratee == null && obj != null) { |
310 | | - obj = isArrayLike(obj) ? obj : _.values(obj); |
311 | | - for (var i = 0, length = obj.length; i < length; i++) { |
312 | | - value = obj[i]; |
313 | | - if (value < result) { |
314 | | - result = value; |
315 | | - } |
316 | 298 | } |
317 | | - } else { |
318 | | - iteratee = cb(iteratee, context); |
319 | | - _.each(obj, function(value, index, list) { |
320 | | - computed = iteratee(value, index, list); |
321 | | - if (computed < lastComputed || computed === Infinity && result === Infinity) { |
322 | | - result = value; |
323 | | - lastComputed = computed; |
324 | | - } |
325 | | - }); |
326 | | - } |
327 | | - return result; |
| 299 | + return result; |
| 300 | + }; |
328 | 301 | }; |
329 | 302 |
|
| 303 | + // Return the extremum element (or element-based computation). |
| 304 | + _.max = createExtremumFinder(true); |
| 305 | + _.min = createExtremumFinder(false); |
| 306 | + |
330 | 307 | // Shuffle a collection, using the modern version of the |
331 | 308 | // [Fisher-Yates shuffle](http://en.wikipedia.org/wiki/Fisher–Yates_shuffle). |
332 | 309 | _.shuffle = function(obj) { |
|
0 commit comments