js寻找并删除数组元素
今天的任务中创建一个destroyer()
函数,其功能是对所给的数组根据参数删除这些元素。也就是说给destroyer()
传入一个参数arr
,而且这个参数是类似这样的[1,2,3,4,5,2,3,1,3],1,3
,要做的事情就是从数组[1,2,3,4,5,2,3,1,3]
删除所有的1
和3
元素。
实现思路
知道要完成的任务之后,要有一个实现思路,其简单的可以概括为:
- 通过
arguments
对象将所有参数包装成一个数组args
- 通过JavaScript的一些方法将
arr
参数移除,也就是需要删除的参数 - 通过
Array.indexOf()
将arr
除外的args
数组做为过滤的条件 - 通过
filter()
方法创建过滤条件,将arr
中符合filter()
条件的元素删除,当然除了通过filter()
之外,还可以使用JavaScript中的for
循环 - 返回最后的
arr
将涉及到的JavaScript方法
有思路了,就好办了,这里简单罗列一些将要用到的JavaScript方法:
上面的知识点是后面所有解决方案都将会涉及到的。为了更好的理解后面的解决方案,简单的回忆一下这几个知识点。
arguments
是一个类数组对象。代表传给一个function
的参数列表。它是函数内部的本地变量,已不再是函数的属必了。可以在函数内部通过使用arguments
对象来获取函数的所有参数。
特别强调了,arguments
对象仅在函数内部有效,在函数外部调用arguments
对象会出现一个错误。来看一个简单的示列:
function destroyer (arr) {
// 将所传的参数转换成数组args
var args = arguments;
console.log(args); //[[1,2,1,3,2,1,3,4,2,6],1,2]
for (var i = 0, len = arguments.length; i < len; i++) {
console.log(arguments[i]);
/*
* i = 0 => arguments[0] = [1,2,1,3,2,1,3,4,2,6]
* i = 1 => arguments[1] = 1
* i = 2 => arguments[2] = 2
*/
}
}
destroyer([1,2,1,3,2,1,3,4,2,6],1,2);
从上面的示例,可以知道,通过arguments[0]
可以获取到的数组arr
,也就是目标数组。同时通过JavaScript的push()
、splice()
或者shift()
之类的方法来删除args
数组中的第一个元素,从而得到需要从arr
中移除的参数,其也是一个数组,比如说将其称为removeArgs
。
其实除了这些方法之外,可以通过arguments
带一个参数,就可以直接得到需要移除的参数removeArgs
数组:
removeArgs = Array.prototype.slice.call(arguments, 1); // [1, 2]
这样一来,就得到了目标数组,比如说将其称之为newArray
和需要移除的数组removeArgs
。那么就可以Array.prototype.indexOf()
获取removeArgs
中的索引值index
,如果其等于-1
,就表示元素不在数组removeArgs
中,否则将返回对应的索引值:
[1,2].indexOf(1) = 0
然后使用===
或者!==
来做比较
removeArgs.indexOf(value) === -1;
如果其值不为-1
将返回false
。
[1,2].indexOf(1) = 0 => false
[1,2].indexOf(2) = 1 => false
而我们的目标就是从newArray
中移除removeArgs
中有相同的元素。比如说:
newArray = [1,2,1,3,2,1,3,4,2,6]
removeArgs= [1,2]
也就是说从[1,2,1,3,2,1,3,4,2,6]
移除所有的1
和2
,最后得到的数组arr
:
arr = [3, 3, 4, 6]
要从一个数组中过滤掉对应的参数,大家肯定会想到filter()
方法,如果其callback
函数返回的值为false
时,就会从数组中删除这个值,从而将符合条件的元素组成一个新的数组。也就是我们最终需要的数组arr
。
解决方案
要实现这个功能,实现方案非常的多,下面罗列一些搜集来的解决方案,以供大家学习和参考:
方法1
function destroyer(arr) {
// 获取目标数组
var newArray = arguments[0]; // [1, 2, 1, 3, 2, 1, 3, 4, 2, 6]
// 声明一个空数组,用来存储需要从`newArray`中删除的元素
var removeArgs = [];
for (var i = 1, len = arguments.length; i < len; i++) {
removeArgs.push(arguments[i]);
/*
* 遍历次数 i len i < len i++ arguments[i] removeArgs
* 1st 1 3 yes 2 1 [1]
* 2nd 2 3 yes 3 2 [1,2]
* 3rd 3 3 no
* end loop
*
*/
}
// 声明filter()方法的callback函数
function isFalse (value) {
return removeArgs.indexOf(value) === -1;
/*
* removeArgs = [1,2]
* removeArgs.indexOf(value) = ? removeArgs.indexOf(value) === -1
* [1,2].indexOf(1) = 0 false
* [1,2].indexOf(2) = 1 false
*
*/
}
return newArray.filter(isFalse);// newArray中删除1,2
}
在Chrome中运行后:
destroyer([1,2,1,3,2,1,3,4,2,6],1,2); // [3, 3, 4, 6]
方法2
function destroyer(arr) {
var newArray = arguments[0]; //[1,2,1,3,2,1,3,4,2,6]
var removeArgs = [];
for (var i = 1, len = arguments.length; i < len; i++) {
removeArgs.push(arguments[i]);
/*
* 遍历次数 i len i < len i++ arguments[i] removeArgs
* 1st 1 3 yes 2 1 [1]
* 2nd 2 3 yes 3 2 [1,2]
* 3rd 3 3 no
* end loop
*
*/
}
function isFalse (value) {
for (var j = 0; j < removeArgs.length; j++) {
if (removeArgs[j] == value) {
return false;
}
/*
* removeArgs = [1,2]
* 遍历次数 j = ? j < removeArgs.length j++ removeArgs[j] value removeArgs[j] == value
* 1st 0 yes 1 1 1 false
* 2nd 1 yes 2 2 2 false
* 3rd 2 no
* end loop
*
*/
}
return true;
}
return newArray.filter(isFalse); // 从newArray数组中删除1,2
}
方法3
function destroyer(arr) {
var args = Array.prototype.slice.call(arguments); // [[1,2,1,3,2,1,3,4,2,6],1,2]
args.splice(0, 1); // 从数组中args删除第一个元素[1,2,1,3,2,1,3,4,2,6], args数组变成[1,2]
// arr = [1, 2, 1, 3, 2, 1, 3, 4, 2, 6]
return arr.filter(function(value) {
return args.indexOf(value) === -1;
});
}
方法4
function destroyer(arr) {
var removeArgs = Array.prototype.slice.call(arguments, 1); // [1, 2]
// arr = [1, 2, 1, 3, 2, 1, 3, 4, 2, 6]
return arr.filter(function(value) {
return removeArgs.indexOf(value) < 0;
});
}
方法5
function destroyer(arr) {
var args = arguments;//[[1, 2, 1, 3, 2, 1, 3, 4, 2, 6], 1, 2]
function isFalse (value) {
for (var i = 1, len = args.length; i < len; i++){
if (args[i] == value) {
return false;
}
}
return true;
}
// arr = [1, 2, 1, 3, 2, 1, 3, 4, 2, 6]
return arr.filter(isFalse);
}
方法6
function destroyer(arr) {
var args = Array.prototype.slice.call(arguments); //[[1, 2, 1, 3, 2, 1, 3, 4, 2, 6], 1, 2]
var newArray = args.shift(); //[1, 2, 1, 3, 2, 1, 3, 4, 2, 6]
// 这里args = [1,2]
function isFalse (a) {
return args.every( function (b) {
return a !== b;
});
}
return newArray.filter(isFalse);
}
方法7
function destroyer(arr) {
var removeArgs = Array.prototype.slice.call(arguments, 1);// [1,2]
function isFalse (a) {
return !removeArgs.some (function (b) {
return a === b;
})
}
return arr.filter(isFalse);
}
方法8
function destroyer(arr) {
var removeArgs = Array.prototype.slice.call(arguments, 1); // [1,2]
removeArgs.forEach(function(value) {
// arr = [1, 2, 1, 3, 2, 1, 3, 4, 2, 6]
var index = arr.indexOf(value);
while (index > -1) {
arr.splice(index, 1);
index = arr.indexOf(value);
}
});
return arr;
}
方法9
function destroyer(arr) {
// arguments = [[1, 2, 1, 3, 2, 1, 3, 4, 2, 6],1,2]
for (var i = 1; i < arguments.length; i++) {
// arr = [1, 2, 1, 3, 2, 1, 3, 4, 2, 6]
for (var j = 0; j < arr.length; j++) {
if (arguments[i] == arr[j]) {
arr.splice(j, 1);
--j;
}
}
}
return arr;
}
也可以换成这样的方式:
function destroyer(arr) {
for (var i = 1; i < arguments.length; i++) {
for (var j = arr.length - 1; j >= 0; j--) {
if (arguments[i] == arr[j]) {
arr.splice(j, 1);
}
}
}
return arr;
}
方法10
除了上述方法之外,还可以使用ES6中的一些方法:
比如:
function destroyer(arr) {
var removeArgs = new Set(Array.prototype.slice.call(arguments, 1)); //Set {1, 2}
function isFalse (value) {
return !removeArgs.has(value);
}
return arr.filter(isFalse);
}
也可以将上述方法改成:
function destroyer(arr, ...items) {
var removeArgs = new Set(items); // Set {1, 2}
function isFalse (value) {
return !removeArgs.has(value);
}
return arr.filter(isFalse);
}