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

相关推荐
CrissChan36 分钟前
Pycharm 函数注释
java·前端·pycharm
小小小小宇1 小时前
Vue.nextTick()笔记
前端
小约翰仓鼠3 小时前
vue3子组件获取并修改父组件的值
前端·javascript·vue.js
Lin Hsüeh-ch'in3 小时前
Vue 学习路线图(从零到实战)
前端·vue.js·学习
烛阴3 小时前
bignumber.js深度解析:驾驭任意精度计算的终极武器
前端·javascript·后端
计蒙不吃鱼3 小时前
一篇文章实现Android图片拼接并保存至相册
android·java·前端
全职计算机毕业设计3 小时前
基于Java Web的校园失物招领平台设计与实现
java·开发语言·前端
你的人类朋友4 小时前
✍️Node.js CMS框架概述:Directus与Strapi详解
javascript·后端·node.js
啊~哈4 小时前
vue3+elementplus表格表头加图标及文字提示
前端·javascript·vue.js