每天一個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 點贊
評論
評論
共同學習,寫下你的評論
評論加載中...
作者其他優質文章
正在加載中
感謝您的支持,我會繼續努力的~
掃碼打賞,你說多少就多少
贊賞金額會直接到老師賬戶
支付方式
打開微信掃一掃,即可進行掃碼打賞哦