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. 函数式编程特性:接收函数作为参数,展现了函数式编程中高阶函数的特点。

相关推荐
web打印社区4 小时前
使用React如何静默打印页面:完整的前端打印解决方案
前端·javascript·vue.js·react.js·pdf·1024程序员节
喜欢踢足球的老罗4 小时前
[特殊字符] PM2 入门实战:从 0 到线上托管 React SPA
前端·react.js·前端框架
小光学长4 小时前
基于Vue的课程达成度分析系统t84pzgwk(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。
前端·数据库·vue.js
Baklib梅梅5 小时前
探码科技再获“专精特新”认定:Baklib引领AI内容管理新方向
前端·ruby on rails·前端框架·ruby
南方以南_5 小时前
Chrome开发者工具
前端·chrome
YiHanXii5 小时前
this 输出题
前端·javascript·1024程序员节
楊无好5 小时前
React中ref
前端·react.js
维他命Coco5 小时前
js常见开发学习
javascript
程琬清君5 小时前
vue3 confirm倒计时
前端·1024程序员节
歪歪1005 小时前
在C#中详细介绍一下Visual Studio中如何使用数据可视化工具
开发语言·前端·c#·visual studio code·visual studio·1024程序员节