Lodash源码阅读-assocIndexOf

Lodash 源码阅读-assocIndexOf

概述

assocIndexOf 是 Lodash 内部使用的辅助函数,用于在键值对数组中查找指定键所在的索引位置。它是 ListCache 缓存实现的核心查找函数,提供了高效的键查找功能。

前置学习

  • eq:判断两个值是否相等的辅助函数,使用 SameValueZero 算法实现

技术知识:

  • JavaScript 数组的遍历
  • JavaScript 中的相等性比较
  • SameValueZero 算法

源码实现

javascript 复制代码
/**
 * Gets the index at which the `key` is found in `array` of key-value pairs.
 *
 * @private
 * @param {Array} array The array to inspect.
 * @param {*} key The key to search for.
 * @returns {number} Returns the index of the matched value, else `-1`.
 */
function assocIndexOf(array, key) {
  var length = array.length;
  while (length--) {
    if (eq(array[length][0], key)) {
      return length;
    }
  }
  return -1;
}

实现思路

assocIndexOf 函数的实现思路非常直接:

  1. 从数组的末尾向前遍历
  2. 对于每个元素,比较其第一个值(键)是否与目标键相等
  3. 如果找到匹配项,立即返回当前索引
  4. 如果遍历完整个数组都没有找到匹配项,返回 -1 表示未找到

函数使用 eq 函数进行键的比较,这确保了正确处理特殊情况(如 NaN)。

源码解析

函数接收两个参数:

  • array: 要搜索的键值对数组,每个元素都是 [key, value] 形式
  • key: 要查找的键

让我们详细解析实现:

  1. var length = array.length;: 获取数组的长度。

  2. while (length--) { ... }: 从数组末尾向前遍历。每次迭代会先使用当前值,然后将 length - 1。这种从后向前遍历的方式是一种常见的优化技巧,因为通常最近添加的元素更可能被查找(利用了时间局部性原理)。

  3. if (eq(array[length][0], key)) { ... }:

    • array[length] 获取当前位置的键值对 [key, value]
    • array[length][0] 获取这个键值对的键
    • eq(array[length][0], key) 使用 eq 函数比较当前元素的键与目标键是否相等
  4. return length;: 如果找到匹配项,立即返回当前索引。

  5. return -1;: 如果遍历完整个数组都没有找到匹配项,返回 -1 表示未找到。

例如:

javascript 复制代码
const arr = [
  ["name", "John"],
  ["age", 30],
  ["city", "New York"],
];
assocIndexOf(arr, "age"); // 返回 1
assocIndexOf(arr, "gender"); // 返回 -1

应用场景

assocIndexOf 在 Lodash 内部主要用于 ListCache 缓存实现中,是其核心查找机制。它在以下场景中被使用:

  1. ListCache.has(key): 检查缓存中是否存在特定键
  2. ListCache.get(key): 获取特定键的值
  3. ListCache.set(key, value): 设置或更新键值对
  4. ListCache.delete(key): 删除指定键的键值对

总结

assocIndexOf 是一个简单而高效的数组查找函数,通过从后向前遍历实现键的快速查找。它具有以下特点:

  1. 简单高效:代码简洁,实现直观,性能良好
  2. 反向遍历:利用时间局部性原理,从数组末尾向前查找,优化常见使用场景
  3. 健壮处理:通过 eq 函数处理各种相等情况,包括 NaN 的正确处理

从设计角度看,我们可以学习到:

  1. 职责单一:函数只负责在数组中查找键,不处理其他逻辑
  2. 封装复杂度:将键的比较逻辑封装在 eq 函数中,简化主函数实现
  3. 优化常见情况:通过反向遍历优化最常见的访问模式

在实际开发中,我们也可以参考这种实现方式,为自定义的数据结构提供高效的查找机制。甚至在处理简单的键值数据时,这种数组实现对于小数据量可能比 Map 或对象更高效。

相关推荐
萧行之9 分钟前
Observable Plot 源码深度解析——4 核心抽象逐项学习
前端·学习·数据可视化
今日无bug26 分钟前
为什么大模型回答总是一个字一个字蹦出来?聊聊 SSE 流式输出与 BFF 层的那些事
前端·llm
志尊宝26 分钟前
Vue3 零基础每日笔记(016):v-for 列表渲染——key 的作用与为什么不能用 index
javascript·vue.js·笔记
CIO_Alliance30 分钟前
AI微调系列(1)| 全量微调、LoRA、QLoRA 三种方案怎么选
前端·人工智能·神经网络·机器学习·embedding·企业ai转型
hanbo17C231 分钟前
企业官网能不能看出公司实力?选建站公司前,先看这6条硬标准
运维·服务器·前端
zzzll111140 分钟前
LLM 学习第 24 课:Agent Harness
前端·人工智能·学习
Bmob后端云41 分钟前
Bmob后端云实战|Python实现SSE流式输出,给备忘录AI加上打字机效果
前端·github
nunumaymax1 小时前
【第九章-React Router 6】
前端·react.js
少冰1 小时前
前端埋点如何落地:从事件设计到上线验收
前端·数据分析·数据可视化
toooooop81 小时前
thinkphp查询数据表最后的自增id
前端·javascript·数据库