# basePullAll
# Description
它的作用是将数组 array 中存在于数组 values 中的元素移除。同时也支持迭代器 iteratee 来用返回新的比较值,也支持 comparator 自定义比较函数
# Params
(array, values, iteratee, comparator)
# Return
Array
# Depend
import map from '../map.js'
import baseIndexOf from './baseIndexOf.js'
import baseIndexOfWith from './baseIndexOfWith.js'
import copyArray from './copyArray.js'
map 源码分析
baseIndexOf 源码分析
baseIndexOfWith 源码分析
copyArray 源码分析
# Code
function basePullAll(array, values, iteratee, comparator) {
const indexOf = comparator ? baseIndexOfWith : baseIndexOf
const length = values.length
let index = -1
let seen = array
if (array === values) {
values = copyArray(values)
}
if (iteratee) {
seen = map(array, (value) => iteratee(value))
}
while (++index < length) {
let fromIndex = 0
const value = values[index]
const computed = iteratee ? iteratee(value) : value
while ((fromIndex = indexOf(seen, computed, fromIndex, comparator)) > -1) {
if (seen !== array) {
seen.splice(fromIndex, 1)
}
array.splice(fromIndex, 1)
}
}
return array
}
# Analyze
- 首先根据是否传入了自定义函数,确定
indexOf
方法,baseIndexOfWith
支持自定义比较函数 - 如果
array === values
, 则表示 二者引用地址相同 ,此时需要重新 copy一份,后续会对array
做修改,如果不copy 会影响到values
,会出错 - 如果 传入了
iteratee
,则表示使用iteratee
处理过的值来进行判断,这里使用map
对array
进行了遍历,拿到了新的数组seen
computed
作为比较的值,这里处理是因为可能存在iteratee
函数,使用iteratee
处理之后的值进行判断- 在第三步时,判断了
iteratee
函数,如果存在,会处理array
成新的seen
,所以这里判断 如果seen !== array
,也需要将seen
对应的值删除 while
循环,如果存在对应的值,拿到下标,进行删除操作
# Remark
- Array.prototype.splice() MDN (opens new window) 方法通过删除或替换现有元素或者原地添加新的元素来修改数组,并以数组形式返回被修改的内容。此方法会改变原数组。
# Example
const a = [1,2,3,4,5]
console.log(basePullAll(a, [1,2,3])) // [4, 5]