_.sortedIndexBy(array, value, [iteratee=_.identity])

37

_.sortedIndexBy(array, value, [iteratee=_.identity])
_.sortedIndexBy和sortedIndex类似,区别是多一个参数遍历器,会处理value和数组的每一个元素
参数

array (Array): 需要查找插入位置的数组
value (*): 需要插入的元素

[iteratee=_.identity] (Function): 遍历器会处理每一个数组元素还有value

返回值

(number): 返回元素应该插入的位置

例子

var objects = [{ 'x': 4 }, { 'x': 5 }];
 
_.sortedIndexBy(objects, { 'x': 4 }, function(o) { return o.x; });
// => 0
 
// The `_.property` iteratee shorthand.
_.sortedIndexBy(objects, { 'x': 4 }, 'x');
// => 0

源代码:

最终生成的源代码第三个参数迭代器也可以直接传字符串,被_.iteratee处理以操作对象属性的情况,这里和differenceBy的源码同理,此处省略。

import baseSortedIndexBy from './.internal/baseSortedIndexBy.js'

/**
 * This method is like `sortedIndex` except that it accepts `iteratee`
 * which is invoked for `value` and each element of `array` to compute their
 * sort ranking. The iteratee is invoked with one argument: (value).
 *
 * @since 4.0.0
 * @category Array
 * @param {Array} array The sorted array to inspect.
 * @param {*} value The value to evaluate.
 * @param {Function} iteratee The iteratee invoked per element.
 * @returns {number} Returns the index at which `value` should be inserted
 *  into `array`.
 * @example
 *
 * const objects = [{ 'n': 4 }, { 'n': 5 }]
 *
 * sortedIndexBy(objects, { 'n': 4 }, ({ n }) => n)
 * // => 0
 */
//和sortedIndex类似,区别是多一个参数遍历器,会处理value和数组的每一个元素
function sortedIndexBy(array, value, iteratee) {
  return baseSortedIndexBy(array, value, iteratee)
}

export default sortedIndexBy
baseSortedIndexBy
import isSymbol from '../isSymbol.js'

/** Used as references for the maximum length and index of an array. */
const MAX_ARRAY_LENGTH = 4294967295
const MAX_ARRAY_INDEX = MAX_ARRAY_LENGTH - 1

/**
 * 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 (value).
 *
 * @private
 * @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`.
 */
//sortedIndexBy和sortedLastIndexBy的基础实现
function baseSortedIndexBy(array, value, iteratee, retHighest) {
  value = iteratee(value)//用遍历器处理value

  let low = 0//区间低位
  let high = array == null ? 0 : array.length//区间高位
  const valIsNaN = value !== value//判断value是不是NaN
  const valIsNull = value === null//判断value是不是Null
  const valIsSymbol = isSymbol(value)//判断value是不是symbol对象
  const valIsUndefined = value === undefined//判断value是不是undefined

  while (low < high) {//循环查找,二分法
    let setLow//是否设置区间低位的标记
    const mid = Math.floor((low + high) / 2)//中间位置索引
    const computed = iteratee(array[mid])//遍历器处理中间位置的值
    const othIsDefined = computed !== undefined//判断computed是不是undefined
    const othIsNull = computed === null//判断computed是不是null
    const othIsReflexive = computed === computed//判断computed是不是NaN
    const othIsSymbol = isSymbol(computed)//判断computed是不是symbol对象

    if (valIsNaN) {
      //如果value是NaN
      //如果有retHighest,设置低位到中间;如果没有retHighest,computed不是NaN,设置低位到中间
      setLow = retHighest || othIsReflexive
    } else if (valIsUndefined) {
      //如果value是undefined
      //如果computed不是NaN,并且有retHithest或者computed不是undefined,设置低位到中间
      setLow = othIsReflexive && (retHighest || othIsDefined)
    } else if (valIsNull) {
      //如果value是null
      //如果computed不是NaN,并且computed不是undefined,并且  有retHighest或者computed不是null,设置低位到中间
      setLow = othIsReflexive && othIsDefined && (retHighest || !othIsNull)
    } else if (valIsSymbol) {
      //如果value是symbol对象
      //如果computed不是NaN,并且computed不是undefined,并且computed不是null,并且有retHighest或者computed不是symbol对象,设置低位到中间
      setLow = othIsReflexive && othIsDefined && !othIsNull && (retHighest || !othIsSymbol)
    } else if (othIsNull || othIsSymbol) {
      //如果computed是null或者symbol对象,设置高位到中间
      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

 

posted @ 2018-10-18 13:30  hahazexia  阅读(422)  评论(0)    收藏  举报