这个方法类似indexOf,除了它是在已经排序的数组array上执行二进制检索

/**
 * 这个方法类似indexOf,除了它是在已经排序的数组array上执行二进制检索
 * This method is like `indexOf` except that it performs a binary search on a sorted `array`
 * @param {Array} array The array to inspect
 * @param {*} value The value to search for
 * @returns {number} Returns the index of the matched value, else `-1`
 * @example
 * sortedIndexOf([4, 5, 5, 5, 6], 5)
 * // => 1
 */

import baseSortedIndex from "./baseSortedIndex"

// 比较两个值以确定他们是否相等
function eq(value, other) {
  return value === other || (value !== value && other !== other)
}

function sortedIndexOf(array, value) {
  var length = array == null ? 0 : array.length
  if (length) {
    var index = baseSortedIndex(array, value)
    if (index < length && eq(array[index], value)) {
      return index
    }
  }
  return -1
}

export default sortedIndexOf
/**
 * The base implementation of `sortedIndex` and `sortedLastIndex` which performs
 * a binaray search of `array` to determine the index at which `value` should be inserted
 * into `array` in order to maintain its sort order
 * @param {Array} array The sorted array to inspect
 * @param {*} value The value to evaluate
 * @param {boolean} [retHighest] Specify returning the highest qualified index
 * @returns {number} Returns the index at which `value` should be inserted into `array`
 */
 
import baseSortedIndexBy from "./baseSortedIndexBy"
const MAX_ARRAY_LENGTH = 4294967295 //Used as references for the maximum length and index of an array
const HALF_MAX_ARRAY_LENGTH = MAX_ARRAY_LENGTH >>> 1 //一半
 
// 这个方法返回首个提供的参数。
function identity(value) {
  return value
}
 
function baseSortedIndex(array, value, retHighest) {
  var low = 0,
    high = array == null ? low : array.length
 
  if (
    typeof value === "number" &&
    value === value &&
    high <= HALF_MAX_ARRAY_LENGTH
  ) {
    while (low < high) {
      var mid = (low + high) >>> 1,
        computed = array[mid]
 
      if (
        computed !== null &&
        (retHighest ? computed <= value : computed < value)
      ) {
        low = mid + 1
      } else {
        high = mid
      }
    }
    return high
  }
  return baseSortedIndexBy(array, value, identity, retHighest)
}
 
export default baseSortedIndex

/**
 * The base implementation of `sortedIndexBy` and `sortedLastIndexBy` which invokes `iteratee` for
 * `value` and each element of `array` to compute their sort ranking.The iteratee is invoked with one argument
 * @param {Array} array The sorted array to inspect
 * @param {*} value The value to evaluate
 * @param {Function} iteratee The iteratee invoked per element
 * @param {boolean} [retHighest] Specify returning the highest qualified index
 * @returns {number} Returns the index at which `value` should be inserted into `array`
 */
 
import isSymbol from "./isSymbol"
const MAX_ARRAY_LENGTH = 4294967295 //Used as references for the maximum length and index of an array
const MAX_ARRAY_INDEX = MAX_ARRAY_LENGTH - 1
 
function baseSortedIndexBy(array, value, iteratee, retHighest) {
  value = iteratee(value)
 
  var low = 0,
    high = array == null ? 0 : array.length,
    valIsNaN = value !== value,
    valIsNull = value === null,
    valIsSymbol = isSymbol(value),
    valIsUndefined = value === undefined
 
  while (low < high) {
    var mid = (low + high) >>> 1,
      computed = iteratee(array[mid]),
      othIsDefined = computed !== undefined,
      othIsNull = computed === null,
      othIsReflexive = computed === computed,
      othIsSymbol = isSymbol(computed)
 
    if (valIsNaN) {
      var setLow = retHighest || othIsReflexive
    } else if (valIsUndefined) {
      setLow = othIsReflexive && (retHighest || othIsDefined)
    } else if (valIsNull) {
      setLow = othIsReflexive && othIsDefined && (retHighest || !othIsNull)
    } else if (valIsSymbol) {
      setLow =
        othIsReflexive &&
        othIsDefined &&
        !othIsNull &&
        (retHighest || !othIsSymbol)
    } else if (othIsNull || othIsSymbol) {
      setLow = false
    } else {
      setLow = retHighest ? computed <= value : computed < value
    }
 
    if (setLow) {
      low = mid + 1
    } else {
      high = mid
    }
  }
 
  return Math.min(high, MAX_ARRAY_INDEX)
}
 
export default baseSortedIndexBy
/**
 * 判断`value`是否是`Symbol`类型
 * Checks if `value` is classified as a `Symbol` primitive or Object.
 *
 * @param {*} value The value to check.
 * @returns {boolean} Returns `true` if `value` is a symbol, else `false`.
 * @example
 *
 * isSymbol(Symbol(3))
 * // => true
 *
 * isSymbol({[Symbol.toStringTag]: 'Symbol'})
 * // => true
 *
 * isSymbol('abc')
 * // => false
 */
 
const symbolTag = "[object Symbol]"
 
function isObjectLike(value) {
  return typeof value == "object" && value !== null
}
 
function isSymbol(value) {
  return (
    typeof value === "symbol" ||
    (isObjectLike(value) && Object.prototype.toString.call(value) === symbolTag)
  )
}
 
export default isSymbol

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值