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

相关推荐
崔庆才丨静觅2 小时前
hCaptcha 验证码图像识别 API 对接教程
前端
passerby60613 小时前
完成前端时间处理的另一块版图
前端·github·web components
掘了3 小时前
「2025 年终总结」在所有失去的人中,我最怀念我自己
前端·后端·年终总结
崔庆才丨静觅3 小时前
实用免费的 Short URL 短链接 API 对接说明
前端
崔庆才丨静觅3 小时前
5分钟快速搭建 AI 平台并用它赚钱!
前端
崔庆才丨静觅4 小时前
比官方便宜一半以上!Midjourney API 申请及使用
前端
Moment4 小时前
富文本编辑器在 AI 时代为什么这么受欢迎
前端·javascript·后端
崔庆才丨静觅4 小时前
刷屏全网的“nano-banana”API接入指南!0.1元/张量产高清创意图,开发者必藏
前端
剪刀石头布啊4 小时前
jwt介绍
前端
爱敲代码的小鱼4 小时前
AJAX(异步交互的技术来实现从服务端中获取数据):
前端·javascript·ajax