Lodash源码阅读-sortedIndexOf

Lodash 源码阅读-sortedIndexOf

概述

sortedIndexOf 是 Lodash 里的一个查找函数,它在已排序的数组中查找某个值的位置。跟普通的 indexOf 比起来,它利用了数组已经排好序的特点,用二分查找的方式快速找到目标,速度比普通查找快很多(时间复杂度从 O(n) 降到 O(log n))。

前置学习

依赖函数

  • baseSortedIndex:内部的二分查找函数,用来找值应该插入的位置
  • eq:判断两个值是否相等的函数,能正确处理各种特殊情况(比如 NaN)

技术知识

  • 二分查找:一种在有序数据中快速查找的算法,每次把查找范围缩小一半
  • 相等性比较:JavaScript 中判断值相等的方法和陷阱
  • 边界检查:避免数组索引越界的常见技巧

源码实现

javascript 复制代码
/**
 * This method is like `_.indexOf` except that it performs a binary
 * search on a sorted `array`.
 *
 * @static
 * @memberOf _
 * @since 4.0.0
 * @category 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
 */
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;
}

实现思路

sortedIndexOf 的思路很直接:

  1. 先检查数组是否为空,空的就直接返回 -1
  2. 用二分查找找到值应该在的位置(第一个大于等于这个值的位置)
  3. 检查一下这个位置上的值是否就是我们要找的值:
    • 是的话,返回这个位置
    • 不是的话,说明数组里没有这个值,返回 -1

这种方法比普通的从头找到尾的方式快多了,特别是在大数组中查找时。

源码解析

边界检查

javascript 复制代码
var length = array == null ? 0 : array.length;
if (length) {
  // 查找逻辑
}
return -1;

先看数组是否为空:

  • 如果传入的 arraynullundefined,就把长度设为 0
  • 只有数组有内容时才进行查找
  • 如果数组是空的,直接返回 -1

这个检查很重要,避免了访问不存在数组的属性而报错。

查找和匹配

javascript 复制代码
var index = baseSortedIndex(array, value);
if (index < length && eq(array[index], value)) {
  return index;
}

这部分是核心逻辑:

  1. baseSortedIndex 找到值应该在的位置
    • 这个函数使用二分查找,找到的是第一个大于等于目标值的位置
  2. 检查两个条件:
    • 找到的位置是否在数组范围内(index < length
    • 该位置的值是否等于要找的值(eq(array[index], value)
  3. 只有当这两个条件都满足时,才返回找到的位置

举个例子说明 index < length 的用处: 假设我们有数组 [1, 3, 5, 7],要查找值 9

  • baseSortedIndex 会返回 4(因为 9 应该插入到数组末尾)
  • 但数组长度只有 4,所以 index < length 条件不满足(4 < 4 为 false)
  • 这就避免了访问 array[4](不存在的元素),防止出现越界错误
  • 函数会直接返回 -1,表示没找到

这个检查确保了即使要查找的值比数组中所有元素都大,函数也能正确处理。

eq 函数比普通的 === 更智能,能正确处理 NaN 等特殊情况。

返回结果

javascript 复制代码
return -1;

如果没找到匹配的值,就返回 -1,这和 JavaScript 原生的 indexOf 行为一致。

总结

sortedIndexOf 这个小函数展示了数据结构和算法的重要性:

  1. 利用数据特性

    • 知道数组已排序后,可以用更高效的算法
    • 二分查找把时间复杂度从 O(n) 降到 O(log n)
  2. 健壮性设计

    • 做好边界检查和异常处理
    • eq 函数解决 JavaScript 相等比较的各种坑
  3. API 设计

    • 保持与原生 indexOf 相同的接口风格
    • 函数名清晰地表明它的用途和适用条件

这种专门针对特定场景优化的函数,是 Lodash 这类工具库价值的体现 ------ 让常见操作变得更简单、更高效。

相关推荐
小小小小宇3 小时前
虚拟列表兼容老DOM操作
前端
悦悦子a啊3 小时前
Python之--基本知识
开发语言·前端·python
安全系统学习4 小时前
系统安全之大模型案例分析
前端·安全·web安全·网络安全·xss
涛哥码咖4 小时前
chrome安装AXURE插件后无效
前端·chrome·axure
OEC小胖胖4 小时前
告别 undefined is not a function:TypeScript 前端开发优势与实践指南
前端·javascript·typescript·web
行云&流水4 小时前
Vue3 Lifecycle Hooks
前端·javascript·vue.js
Sally璐璐4 小时前
零基础学HTML和CSS:网页设计入门
前端·css
老虎06275 小时前
JavaWeb(苍穹外卖)--学习笔记04(前端:HTML,CSS,JavaScript)
前端·javascript·css·笔记·学习·html
三水气象台5 小时前
用户中心Vue3网页开发(1.0版)
javascript·css·vue.js·typescript·前端框架·html·anti-design-vue
灿灿121385 小时前
CSS 文字浮雕效果:巧用 text-shadow 实现 3D 立体文字
前端·css