lodash源码分析每日一练 - 数组 - intersection / intersectionBy / intersectionWith

今日分享:

每一步都是曼妙的风景~
lodash官网地址

_.intersection([arrays])

使用:
创建唯一值的数组,这个数组包含所有给定数组都包含的元素,使用SameValueZero进行相等性比较。(注:可以理解为给定数组的交集)

使用示例:

_.intersection([2, 1], [4, 2], [1, 2]);
// => [2]

尝试手写:

①返回数组 ②“查重” ③ 返回重合部分

    let inter_arr1 = [5, 2],inter_arr2 = [2, 1],inter_arr3 = [4, 2];function my_intersection (...args) {let n = 0,len = args[0].length, arr = [];while (n<len) {for(let i = 0; i < args.length; i++) {if(args[i].indexOf(args[0][n]) === -1) {break;}if(i == args.length -1) {arr.push(args[0][n])}}n++;}return arr;}console.log(my_intersection(inter_arr1, inter_arr2, inter_arr3)); // [2]

源码方案:

var intersection = baseRest(function(arrays) {
// 判断并取出array中的每一项都是键值对类型var mapped = arrayMap(arrays, castArrayLikeObject);return (mapped.length && mapped[0] === arrays[0])? baseIntersection(mapped): [];
});
var nativeMin = Math.min;
// 核心处理逻辑
/*** The base implementation of methods like `_.intersection`, without support* for iteratee shorthands, that accepts an array of arrays to inspect.** @private* @param {Array} arrays The arrays to inspect.* @param {Function} [iteratee] The iteratee invoked per element.* @param {Function} [comparator] The comparator invoked per element.* @returns {Array} Returns the new array of shared values.*/
function baseIntersection(arrays, iteratee, comparator) {
// 通过参数 comparator 确定使用哪种比较函数var includes = comparator ? arrayIncludesWith : arrayIncludes,  		length = arrays[0].length,// 取第一项lengthothLength = arrays.length,// 全部要比较的数组长度othIndex = othLength, // 全部要比较的数组下标caches = Array(othLength), // 声明一个空数组maxLength = Infinity, // 最大长度result = []; // 声明一个空数组用来存放结果while (othIndex--) {var array = arrays[othIndex];// 存在迭代器,先迭代再比较if (othIndex && iteratee) {array = arrayMap(array, baseUnary(iteratee));}// 取数组长度和最大长度的小值maxLength = nativeMin(array.length, maxLength);// 如果存在比较器并 需要迭代处理内容或数组内容过多,则使用setcache去处理caches[othIndex] = !comparator && (iteratee || (length >= 120 && array.length >= 120))? new SetCache(othIndex && array): undefined;}array = arrays[0];var index = -1,seen = caches[0];outer:while (++index < length && result.length < maxLength) {var value = array[index],computed = iteratee ? iteratee(value) : value;value = (comparator || value !== 0) ? value : 0;if (!(seen? cacheHas(seen, computed): includes(result, computed, comparator))) {othIndex = othLength;while (--othIndex) {var cache = caches[othIndex];if (!(cache? cacheHas(cache, computed): includes(arrays[othIndex], computed, comparator))) {continue outer;}}if (seen) {seen.push(computed);}result.push(value);}}return result;
}

相关方法

__.ntersectionBy([arrays], [iteratee=_.identity])

使用:
这个方法类似_.intersection,区别是它接受一个 iteratee 调用每一个arrays的每个值以产生一个值,通过产生的值进行了比较。结果值是从第一数组中选择。iteratee 会传入一个参数:(value)。
使用示例:

_.intersectionBy([2.1, 1.2], [4.3, 2.4], Math.floor);
// => [2.1]// The `_.property` iteratee shorthand.
_.intersectionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
// => [{ 'x': 1 }]

源码方案

var intersectionBy = baseRest(function(arrays) {var iteratee = last(arrays),mapped = arrayMap(arrays, castArrayLikeObject);if (iteratee === last(mapped)) {iteratee = undefined;} else {mapped.pop();}return (mapped.length && mapped[0] === arrays[0])? baseIntersection(mapped, baseIteratee(iteratee, 2)): [];
});
_.intersectionWith([arrays], [comparator])

使用:
这个方法类似_.intersection,区别是它接受一个 comparator 调用比较arrays中的元素。结果值是从第一数组中选择。comparator 会传入两个参数:(arrVal, othVal)。
使用示例:

var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }];_.intersectionWith(objects, others, _.isEqual);
// => [{ 'x': 1, 'y': 2 }]

源码方案

var intersectionWith = baseRest(function(arrays) {var comparator = last(arrays),mapped = arrayMap(arrays, castArrayLikeObject);comparator = typeof comparator == 'function' ? comparator : undefined;if (comparator) {mapped.pop();}return (mapped.length && mapped[0] === arrays[0])? baseIntersection(mapped, undefined, comparator): [];
});

思考

lodash在实践中非常方便,不用担心会出现莫名其妙的意外bug,数据格式不正确顶多结果为空。
但是稍微复杂一点的逻辑处理,就会涉及很多子方法的调用,像以上对比取重,其实只需要两个循环逻辑去一一对比就好,只是选双指针或者别的对比方式去优化处理性能的区别。有点不确定使用lodash对数据处理时是否对性能方面消耗较大。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/580978.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

箭头函数的泛型,typescript中怎么写

TypeScript——泛型&#xff08;函数泛型、模板类型可以是多个、泛型的错误、泛型函数变量、泛型函数类型接口、泛型类1、泛型类2、泛型约束、泛型参数的默认类型&#xff09;、声明文件、Vue3.0集成ts_typescript 泛型函数-CSDN博客

JavaScript----条件语句

1. 条件语句的介绍 条件语句就是通过条件来控制程序的走向 2. 条件语句语法 if 语句 - 只有当指定条件为 true 时&#xff0c;使用该语句来执行代码if...else 语句 - 当条件为 true 时执行代码&#xff0c;当条件为 false 时执行其他代码if...else if....else 语句 - 使用该…

【C语言】自定义类型:结构体深入解析(三)结构体实现位段最终篇

文章目录 &#x1f4dd;前言&#x1f320;什么是位段&#xff1f;&#x1f309; 位段的内存分配&#x1f309;VS怎么开辟位段空间呢&#xff1f;&#x1f309;位段的跨平台问题&#x1f320; 位段的应⽤&#x1f320;位段使⽤的注意事项&#x1f6a9;总结 &#x1f4dd;前言 本…

第40节: Vue3 注册生命周期钩子

在UniApp中使用Vue3框架时&#xff0c;你可以注册生命周期钩子来执行特定的逻辑。以下是一个示例&#xff0c;演示了如何在UniApp中使用Vue3框架注册生命周期钩子&#xff1a; <template> <view> <p>{{ message }}</p> </view> </templ…

大数据HCIE成神之路之数据预处理(6)——特征编码

特征编码 1.1 独热编码1.1.1 实验任务1.1.1.1 实验背景1.1.1.2 实验目标1.1.1.3 实验数据解析1.1.2 实验思路1.1.3 实验操作步骤1.1.4 结果验证1.2 Label-Encoding1.2.1 实验任务1.2.1.1 实验背景1.2.1.2 实验目标1.2.1.3 实验数据解析1.2.2 实验思路1.2.3 实验操作步骤1.2.4 结…

C中的extern关键字

C中的extern关键字应用于C变量&#xff08;数据对象&#xff09;和C函数。基本上&#xff0c;extern关键字扩展了C变量和C函数的可见性。这可能就是它诶命名为extern的原因。 虽然大多数人可能理解变量或函数的“声明&#xff08;declaration&#xff09;” 和 “定义&#xf…

月薪高达6W,多家大厂急招鸿蒙开发工程师,现在转还来得及吗?

近期&#xff0c;“安卓版本与鸿蒙不再兼容”的词条登上微博热搜&#xff0c;华为鸿蒙加速按下向“纯血鸿蒙”蜕变的启动键&#xff0c;欲与 iOS、安卓在市场三分天下。 一批嗅觉灵敏的互联网大厂&#xff0c;已经完成或开始启动开发鸿蒙原生 APP&#xff0c;也于近期发布了和…

十、Shell 变量类型

Shell 支持不同类型的变量&#xff0c;其中一些主要的类型如下&#xff1a; 一、整数变量 整型变量用于存储整数据数据。可以使用整数赋值给变量&#xff0c;或者通过命令的输出结果获取整数值。整型变量可以用于数学计算、循环控制等等。 #!/bin/bash num110 num25 su…

Java之ThreadLocal 详解

ThreadLocal 详解 原文地址&#xff1a;https://juejin.cn/post/6844904151567040519open in new window。 什么是ThreadLocal&#xff1f; ThreadLocal提供线程局部变量。这些变量与正常的变量不同&#xff0c;因为每一个线程在访问ThreadLocal实例的时候&#xff08;通过其…

视频流媒体直播云服务管理平台EasyNVS长时间运行出现崩溃情况是什么原因?该如何解决?

EasyNVS云管理平台具备汇聚与管理EasyGBS、EasyNVR等平台的能力&#xff0c;可以将接入的视频资源实现统一的视频能力输出&#xff0c;支持远程可视化运维等管理功能&#xff0c;还能解决设备现场没有固定公网IP却需要在公网直播的需求。 有用户反馈&#xff0c;在长时间不间断…

CGAL的D维范围树和线段树

范围树和线段树是两种数据结构&#xff0c;用于高效地处理和查询数据。 范围树&#xff08;Range Tree&#xff09;是一种二叉树&#xff0c;它通过递归地将每个节点分割成两个子节点来存储一个点集。每个节点表示一个范围&#xff0c;并且存储该范围内所有点的最小和最大值。范…

Mybatis 动态 SQL - script,bind,多数据库支持

script 在使用注解的映射器类中使用动态SQL时&#xff0c;可以使用<script>元素。例如&#xff1a; Update({"<script>","update Author"," <set>"," <if testusername ! null>username#{username},</if&g…

静物摄影在UE5里运用几点记要

被摄体&#xff0c;相机与光源的关系&#xff0c;要增强立体感&#xff0c;摄像机与光源的位置关系要错开&#xff1b;b的立体感要更强 漫反射与点光源&#xff0c;UE5太阳光属于漫反射&#xff0c;整体比较柔和&#xff0c;但是阴影处比较黑&#xff1b;摄影棚会用反光板来增亮…

如何让别人在你的私域疯狂消费?

要让别人在你的私域疯狂消费&#xff0c;首先&#xff0c;你得先打造自己的私域流量池。而打造私域流量池就需要明确你的目标客户群体&#xff0c;理解并满足他们的需求&#xff0c;有意识地向他们提供有价值的内容。 同时&#xff0c;通过创造力&#xff0c;精细化运营以及产品…

【模型】模型量化技术:动态范围、全整数和Float16量化

目录 一 动态范围量化 二 全整数量化 三 float16量化 通常&#xff0c;表示神经网络的数据类型是32位浮点数&#xff08;float32&#xff09;&#xff0c;这种数据类型可以提供高精度的计算&#xff0c;但是在计算资源和存储空间有限的设备上运行神经网络时&#xff0c;会带…

SpringBoot 异步编程浅谈

1. 需求背景 当我们需要提高系统的并发性能时&#xff0c;我们可以将耗时的操作异步执行&#xff0c;从而避免线程阻塞&#xff0c;提高系统的并发性能。例如&#xff0c;在处理大量的并发请求时&#xff0c;如果每个请求都是同步阻塞的方式处 理&#xff0c;系统的响应时间会…

Git使用教程 gittutorial

该教程对该文章的翻译&#xff1a;https://git-scm.com/docs/gittutorial 本文介绍怎用使用 Git 导入新的工程、修改文件及如何其他人同步开发。 首先&#xff0c; 可以使用以下指令获取文档帮助 git help log笔者注&#xff1a;不建议看这个文档&#xff0c;标准的语法介绍…

FreeRTOS的学习

1.创建函数和删除 动态创建为FreeRTOS分配的堆栈&#xff08;方便&#xff09;&#xff0c;而静态创建为人为分配空间。动态应用多任务中必须有while&#xff08;1&#xff09;否则只会执行一次任务中的延时要用 vTaskDelay(500); 延时期间执行其它任务 任务中的延时使…

postman进阶使用

前言 对于postman的基础其实很容易上手实现&#xff0c;也有很多教程。 对于小编我来说&#xff0c;也基本可以实现开发任务。 但是今年我们的高级测试&#xff0c;搞了一下postman&#xff0c;省去很多工作&#xff0c;让我感觉很有必要学一下 这篇文章是在 高级测试工程师ht…

01-Spring Security框架的认证和授权测试

Spring Security 介绍 认证功能与业务无关几乎是每个项目都要具备的功能,市面上有很多认证框架如Apache Shiro、CAS、Spring Security等 Spring Security是Spring家族的一份子且和Spring Cloud集成的很好&#xff0c;所以本项目采用Spring Security作为认证服务的技术框架 …