Lodash源码阅读-sortedUniqBy

Lodash 源码阅读-sortedUniqBy

概述

sortedUniqBy 是 Lodash 中的一个数组去重函数,专门为已排序数组设计并优化。与普通的 uniqBy 不同,它利用数组已排序的特性,使用更高效的算法进行去重操作。该函数接受一个可选的迭代器参数,可以在比较元素前对元素进行转换,最终返回一个新的无重复元素的数组。

前置学习

依赖函数

  • baseSortedUniq:用于有序数组去重的基础函数,是 sortedUniqBy 的核心实现
  • getIteratee:获取适当的迭代器函数,可以将各种类型的参数转换为标准迭代器函数

技术知识

  • 排序数组的特性:相同元素在排序数组中会相邻,可以简化去重算法
  • 迭代器模式:通过迭代器对元素进行转换后再比较
  • 函数式编程:使用高阶函数处理数据转换
  • 参数校验:处理边界情况,如空数组或 undefined

源码实现

javascript 复制代码
function sortedUniqBy(array, iteratee) {
  return array && array.length
    ? baseSortedUniq(array, getIteratee(iteratee, 2))
    : [];
}

实现思路

sortedUniqBy 函数实现非常简洁,主要分为以下几个步骤:

  1. 首先检查输入数组是否存在且有长度,如果没有则直接返回空数组
  2. 使用 getIteratee 获取标准化的迭代器函数,传入参数 2 表示迭代器期望接收两个参数
  3. 调用 baseSortedUniq 执行实际的去重逻辑,传入数组和标准化后的迭代器
  4. 返回去重后的新数组

相比于普通的 uniqBysortedUniqBy 针对已排序数组做了特殊优化。由于排序数组中重复元素总是相邻的,所以只需要与前一个转换后的值比较,而不需要与所有已见过的值比较,这大大提高了性能。

源码解析

1. 函数签名与参数

javascript 复制代码
function sortedUniqBy(array, iteratee) {

函数接收两个参数:

  • array:要去重的排序数组
  • iteratee:可选的迭代器函数,对数组元素进行转换后再比较

2. 边界条件检查

javascript 复制代码
return array && array.length
  ? baseSortedUniq(array, getIteratee(iteratee, 2))
  : [];

这一行代码首先检查 array 是否为有效数组(存在且有长度):

  • 如果是空数组或非数组值(如 null、undefined),则直接返回空数组 []
  • 否则,继续执行去重逻辑

3. 迭代器处理

javascript 复制代码
getIteratee(iteratee, 2);

getIteratee 函数用于处理各种类型的迭代器参数,确保返回标准的函数形式:

  • 如果 iteratee 是函数,则直接使用
  • 如果是对象、字符串或其他值,会转换为相应的属性访问函数或匹配函数
  • 参数 2 表示迭代器期望接收两个参数(值和索引)

4. 核心去重逻辑

baseSortedUniq 函数通过一次遍历实现去重,主要利用排序数组的一个关键特性:相同的元素在排序后必然相邻。因此,只需要将当前元素与前一个元素比较,如果不相同则加入结果数组。

这种方法比通用的 uniq 更高效,因为它只需要 O(n) 的时间复杂度,而不需要使用哈希表或者多次比较。

总结

sortedUniqBy 是一个为已排序数组专门设计的去重函数,它巧妙地利用了排序数组中重复元素相邻的特性,实现了线性时间复杂度的去重操作,比通用的去重函数更高效。

主要特点和优势:

  1. 性能优化:针对已排序数组,只需要与前一个元素比较,时间复杂度为 O(n)
  2. 灵活性:支持自定义迭代器,可以在比较前对元素进行转换
  3. 一致性:保持与其他 Lodash 函数一致的接口和行为
  4. 健壮性 :正确处理边界情况和特殊值(如 0

在处理大型已排序数据集时,sortedUniqBy 比通用的 uniqBy 更为高效,是数据去重的优选工具。

相关推荐
前端大卫6 小时前
Vue3 + Element-Plus 自定义虚拟表格滚动实现方案【附源码】
前端
却尘6 小时前
Next.js 请求最佳实践 - vercel 2026一月发布指南
前端·react.js·next.js
ccnocare6 小时前
浅浅看一下设计模式
前端
Lee川6 小时前
🎬 从标签到屏幕:揭秘现代网页构建与适配之道
前端·面试
Ticnix7 小时前
ECharts初始化、销毁、resize 适配组件封装(含完整封装代码)
前端·echarts
纯爱掌门人7 小时前
终焉轮回里,藏着 AI 与人类的答案
前端·人工智能·aigc
twl7 小时前
OpenClaw 深度技术解析
前端
崔庆才丨静觅7 小时前
比官方便宜一半以上!Grok API 申请及使用
前端
星光不问赶路人7 小时前
vue3使用jsx语法详解
前端·vue.js
天蓝色的鱼鱼7 小时前
shadcn/ui,给你一个真正可控的UI组件库
前端