_extremum.js 1.5 KB

1234567891011121314151617181920212223242526272829303132333435
  1. var identity = require('./identity.js');
  2. var _cb = require('./_cb.js');
  3. var find = require('./find.js');
  4. // The general algorithm behind `_.min` and `_.max`. `compare` should return
  5. // `true` if its first argument is more extreme than (i.e., should be preferred
  6. // over) its second argument, `false` otherwise. `iteratee` and `context`, like
  7. // in other collection functions, let you map the actual values in `collection`
  8. // to the values to `compare`. `decide` is an optional customization point
  9. // which is only present for historical reasons; please don't use it, as it will
  10. // likely be removed in the future.
  11. function extremum(collection, compare, iteratee, context, decide) {
  12. decide || (decide = identity);
  13. // `extremum` is essentially a combined map+reduce with **two** accumulators:
  14. // `result` and `iterResult`, respectively the unmapped and the mapped version
  15. // corresponding to the same element.
  16. var result, iterResult;
  17. iteratee = _cb(iteratee, context);
  18. var first = true;
  19. find(collection, function(value, key) {
  20. var iterValue = iteratee(value, key, collection);
  21. if (first || compare(iterValue, iterResult)) {
  22. result = value;
  23. iterResult = iterValue;
  24. first = false;
  25. }
  26. });
  27. // `extremum` normally returns an unmapped element from `collection`. However,
  28. // `_.min` and `_.max` forcibly return a number even if there is no element
  29. // that maps to a numeric value. Passing both accumulators through `decide`
  30. // before returning enables this behavior.
  31. return decide(result, iterResult);
  32. }
  33. module.exports = extremum;