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 更为高效,是数据去重的优选工具。

相关推荐
香蕉可乐荷包蛋4 小时前
浅入ES5、ES6(ES2015)、ES2023(ES14)版本对比,及使用建议---ES6就够用(个人觉得)
前端·javascript·es6
未来之窗软件服务5 小时前
资源管理器必要性———仙盟创梦IDE
前端·javascript·ide·仙盟创梦ide
liuyang___6 小时前
第一次经历项目上线
前端·typescript
西哥写代码6 小时前
基于cornerstone3D的dicom影像浏览器 第十八章 自定义序列自动播放条
前端·javascript·vue
清风细雨_林木木6 小时前
Vue 中生成源码映射文件,配置 map
前端·javascript·vue.js
FungLeo6 小时前
node 后端和浏览器前端,有关 RSA 非对称加密的完整实践, 前后端匹配的代码演示
前端·非对称加密·rsa 加密·node 后端
雪芽蓝域zzs7 小时前
JavaScript splice() 方法
开发语言·javascript·ecmascript
不灭锦鲤7 小时前
xss-labs靶场第11-14关基础详解
前端·xss
不是吧这都有重名7 小时前
利用systemd启动部署在服务器上的web应用
运维·服务器·前端
霸王蟹7 小时前
React中巧妙使用异步组件Suspense优化页面性能。
前端·笔记·学习·react.js·前端框架