每天一个lodash方法(7)
标签:
JavaScript
Array method 系列之七 —— intersectionintersection
和difference
是功能相反的两个方法。difference
是抛出数组中相同的部分,留下不同的部分,即取补集。
而intersection
是留下相同的部分,即取交集。
intersection
系列包含三个方法:intersection
、intersectionBy
、intersectionWith
。
和difference
系列相似,intersection
提供多个数组的基础比较取交集。intersectionBy
利用iteratee
方法对数组元素进行预先处理。intersectionWith
利用comparator
比较器自定义比较方法。
但是三种方法的思路很相似。
对参数进行预处理。得到
array
,comparator
,iteratee
。执行
baseIntersection
方法
根据数组长度判断是否缓存。缓存源码此处略过。
双重遍历:判断第一个数组的每个元素是否包含在其余数组中。
结果返回。
以下是源码。
// intersection.js// 注意此处传参是...arraysfunction intersection(...arrays) { // 参数处理 const mapped = map(arrays, castArrayLikeObject) // 执行核心方法 return (mapped.length && mapped[0] === arrays[0]) ? baseIntersection(mapped) : [] }// intersectionBy.jsfunction intersectionBy(...arrays) { let iteratee = last(arrays) const mapped = map(arrays, castArrayLikeObject) if (iteratee === last(mapped)) { iteratee = undefined } else { mapped.pop() } // 以上为参数处理,分离得到数组和迭代器 return (mapped.length && mapped[0] === arrays[0]) ? baseIntersection(mapped, iteratee) : [] }// intersectionWith.jsfunction intersectionWith(...arrays) { let comparator = last(arrays) const mapped = map(arrays, castArrayLikeObject) comparator = typeof comparator == 'function' ? comparator : undefined if (comparator) { mapped.pop() } // 以上为参数处理,分离得到数组和比较器 return (mapped.length && mapped[0] === arrays[0]) ? baseIntersection(mapped, undefined, comparator) : [] }
duangduangduang,核心算法出炉。
// baseIntersectionfunction baseIntersection(arrays, iteratee, comparator) { // includes方法,判断数组array中是否含有目标元素value const includes = comparator ? arrayIncludesWith : arrayIncludes const length = arrays[0].length const othLength = arrays.length const caches = new Array(othLength) const result = [] let array let maxLength = Infinity let othIndex = othLength // arrays进行查询的数组集合 while (othIndex--) { // array为数组中的每个元素,即每个需要查询的数组 array = arrays[othIndex] if (othIndex && iteratee) { array = map(array, (value) => iteratee(value)) } maxLength = Math.min(array.length, maxLength) // 设置缓存集合,缓存集合caches的每个元素标识与之相对应的数组元素是否需要缓存 caches[othIndex] = !comparator && (iteratee || (length >= 120 && array.length >= 120)) ? new SetCache(othIndex && array) : undefined } // 将array中的第一个元素设置为比较标准 array = arrays[0] let index = -1 const seen = caches[0] outer: while (++index < length && result.length < maxLength) { // 外层遍历:遍历array数组中的每个元素,赋值为value let value = array[index] const computed = iteratee ? iteratee(value) : value value = (comparator || value !== 0) ? value : 0 // 判断条件:若结果数组result中不包含当前元素value,继续执行算法。 if (!(seen ? cacheHas(seen, computed) : includes(result, computed, comparator) )) { othIndex = othLength while (--othIndex) { const cache = caches[othIndex] // 内层遍历:遍历arrays数组集合除了第一项的所有数组,如果该数组包含value元素,将元素push到result中 if (!(cache ? cacheHas(cache, computed) : includes(arrays[othIndex], computed, comparator)) ) { continue outer } } if (seen) { seen.push(computed) } result.push(value) } } return result }
作者:公子七
链接:https://www.jianshu.com/p/5dbec3bf6679
点击查看更多内容
为 TA 点赞
评论
共同学习,写下你的评论
评论加载中...
作者其他优质文章
正在加载中
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦