Lodash源码阅读-baseIndexOfWith

Lodash 源码阅读-baseIndexOfWith

一、功能概述

baseIndexOfWith 是 Lodash 中的一个内部基础工具函数,它提供了一个更灵活的数组元素查找机制。与 baseIndexOf 不同,该函数允许自定义比较器(comparator)来判断元素是否匹配,这使得它能够支持复杂的相等性判断。

二、前置学习

在深入理解 baseIndexOfWith 函数之前,建议先了解以下相关概念:

  • 比较器函数(Comparator):接收两个参数并返回布尔值的函数,用于确定两个值是否相等
  • 高阶函数:接收函数作为参数的函数
  • baseIndexOf:基础的索引查找函数

三、源码实现

js 复制代码
/**
 * This function is like `baseIndexOf` except that it accepts a comparator.
 *
 * @private
 * @param {Array} array The array to inspect.
 * @param {*} value The value to search for.
 * @param {number} fromIndex The index to search from.
 * @param {Function} comparator The comparator invoked per element.
 * @returns {number} Returns the index of the matched value, else `-1`.
 */
function baseIndexOfWith(array, value, fromIndex, comparator) {
  var index = fromIndex - 1,
    length = array.length;

  while (++index < length) {
    if (comparator(array[index], value)) {
      return index;
    }
  }
  return -1;
}

四、实现原理

1. 整体思路

baseIndexOfWith 函数的设计非常直接,它通过以下步骤工作:

  1. 从指定的起始位置(fromIndex)开始遍历数组
  2. 对每个元素,使用自定义比较器函数(comparator)与目标值进行比较
  3. 当比较器返回 true 时,表示找到匹配元素,返回当前索引
  4. 如果遍历完整个数组都没有找到匹配元素,则返回 -1

相比 baseIndexOfbaseIndexOfWith 的核心优势在于它的灵活性:你可以自定义如何判断两个值是否相等,而不局限于严格相等(===)或特定的 NaN 处理。

2. 参数说明

  • array:要搜索的数组
  • value:要查找的值
  • fromIndex:从哪个位置开始查找(索引值)
  • comparator:比较器函数,接收两个参数(当前元素和要查找的值),返回布尔值

3. 逐行解析

js 复制代码
var index = fromIndex - 1,
  length = array.length;
  • 初始化索引变量,设为 fromIndex - 1,是因为后续使用前置递增(++index
  • 缓存数组长度,避免在循环中重复获取
js 复制代码
while (++index < length) {
  • 使用前置递增操作符(++index)实现从 fromIndex 开始的遍历
  • 遍历直到数组末尾
js 复制代码
if (comparator(array[index], value)) {
  return index;
}
  • 调用自定义比较器函数,比较当前元素与目标值
  • 如果比较器返回 true,表示找到匹配,立即返回当前索引
js 复制代码
return -1;
  • 如果循环结束后没有找到匹配元素,返回 -1,这是数组查找方法的标准约定

五、使用示例

虽然 baseIndexOfWith 是 Lodash 的内部函数,但我们可以模拟其用法以理解其功能:

js 复制代码
// 1. 基本使用 - 自定义相等性比较
const array = [{ id: 1 }, { id: 2 }, { id: 3 }, { id: 2 }];
const customComparator = (element, target) => element.id === target.id;

baseIndexOfWith(array, { id: 2 }, 0, customComparator); // => 1
baseIndexOfWith(array, { id: 2 }, 2, customComparator); // => 3 (从索引2开始查找)

// 2. 模糊匹配 - 字符串包含关系
const strings = ["apple", "banana", "cherry", "date"];
const includesComparator = (element, search) => element.includes(search);

baseIndexOfWith(strings, "an", 0, includesComparator); // => 1 (banana 包含 "an")

// 3. 数值范围比较
const numbers = [10, 20, 30, 40, 50];
const rangeComparator = (element, range) =>
  element >= range[0] && element <= range[1];

baseIndexOfWith(numbers, [25, 45], 0, rangeComparator); // => 2 (30在25-45范围内)

// 4. 使用Lodash的自带比较器
// 假设我们使用 _.isEqual 作为比较器
const deepComparator = _.isEqual;
const complexArray = [
  [1, 2],
  [3, 4],
  [5, 6],
];

baseIndexOfWith(complexArray, [3, 4], 0, deepComparator); // => 1

六、总结

  1. 灵活性提升 :通过允许自定义比较器,baseIndexOfWith 大幅提升了数组查找的灵活性,能够应对各种复杂场景。

  2. 函数设计:函数设计简洁明了,参数排列逻辑清晰,遵循了"最后一个参数是回调"的惯例。

  3. 函数式编程特性:接收函数作为参数,展现了函数式编程中高阶函数的特点。

相关推荐
juruiyuan11129 分钟前
FFmpeg3.4 libavcodec协议框架增加新的decode协议
前端
Peter 谭1 小时前
React Hooks 实现原理深度解析:从基础到源码级理解
前端·javascript·react.js·前端框架·ecmascript
周胡杰1 小时前
鸿蒙接入flutter环境变量配置windows-命令行或者手动配置-到项目的创建-运行demo项目
javascript·windows·flutter·华为·harmonyos·鸿蒙·鸿蒙系统
LuckyLay2 小时前
React百日学习计划——Deepseek版
前端·学习·react.js
gxn_mmf2 小时前
典籍知识问答重新生成和消息修改Bug修改
前端·bug
hj10432 小时前
【fastadmin开发实战】在前端页面中使用bootstraptable以及表格中实现文件上传
前端
乌夷3 小时前
axios结合AbortController取消文件上传
开发语言·前端·javascript
晓晓莺歌3 小时前
图片的require问题
前端
码农黛兮_463 小时前
CSS3 基础知识、原理及与CSS的区别
前端·css·css3
水银嘻嘻4 小时前
web 自动化之 Unittest 四大组件
运维·前端·自动化