_baseSortedIndexBy.js 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. var isSymbol = require('./isSymbol');
  2. /** Used as references for the maximum length and index of an array. */
  3. var MAX_ARRAY_LENGTH = 4294967295,
  4. MAX_ARRAY_INDEX = MAX_ARRAY_LENGTH - 1;
  5. /* Built-in method references for those with the same name as other `lodash` methods. */
  6. var nativeFloor = Math.floor,
  7. nativeMin = Math.min;
  8. /**
  9. * The base implementation of `_.sortedIndexBy` and `_.sortedLastIndexBy`
  10. * which invokes `iteratee` for `value` and each element of `array` to compute
  11. * their sort ranking. The iteratee is invoked with one argument; (value).
  12. *
  13. * @private
  14. * @param {Array} array The sorted array to inspect.
  15. * @param {*} value The value to evaluate.
  16. * @param {Function} iteratee The iteratee invoked per element.
  17. * @param {boolean} [retHighest] Specify returning the highest qualified index.
  18. * @returns {number} Returns the index at which `value` should be inserted
  19. * into `array`.
  20. */
  21. function baseSortedIndexBy(array, value, iteratee, retHighest) {
  22. var low = 0,
  23. high = array == null ? 0 : array.length;
  24. if (high === 0) {
  25. return 0;
  26. }
  27. value = iteratee(value);
  28. var valIsNaN = value !== value,
  29. valIsNull = value === null,
  30. valIsSymbol = isSymbol(value),
  31. valIsUndefined = value === undefined;
  32. while (low < high) {
  33. var mid = nativeFloor((low + high) / 2),
  34. computed = iteratee(array[mid]),
  35. othIsDefined = computed !== undefined,
  36. othIsNull = computed === null,
  37. othIsReflexive = computed === computed,
  38. othIsSymbol = isSymbol(computed);
  39. if (valIsNaN) {
  40. var setLow = retHighest || othIsReflexive;
  41. } else if (valIsUndefined) {
  42. setLow = othIsReflexive && (retHighest || othIsDefined);
  43. } else if (valIsNull) {
  44. setLow = othIsReflexive && othIsDefined && (retHighest || !othIsNull);
  45. } else if (valIsSymbol) {
  46. setLow = othIsReflexive && othIsDefined && !othIsNull && (retHighest || !othIsSymbol);
  47. } else if (othIsNull || othIsSymbol) {
  48. setLow = false;
  49. } else {
  50. setLow = retHighest ? (computed <= value) : (computed < value);
  51. }
  52. if (setLow) {
  53. low = mid + 1;
  54. } else {
  55. high = mid;
  56. }
  57. }
  58. return nativeMin(high, MAX_ARRAY_INDEX);
  59. }
  60. module.exports = baseSortedIndexBy;