@色少10年前
废话不多说直接上题目!关于数组去重的例子
数组arr1和arr2,长度不固定,如何从arr1中删除和arr2中重复值的元素?
如:
var arr1=[1,3,4,6,7]; var arr2=[3,4,7]; ====> var arr3=[1,6] console.log()
//* ==================================================================================*//
思路1:
假如数组中的元素全是数字可以直接利用正则匹配
console.log(arr1.concat(arr2).sort().join(”).replace(/(w)1+/g,”).split(”))
思路2:
数组中包含其他类型的字符,比如:
var arr=[1,2,3,’1′,’2′,’3′,1,2]
利用hash表。把已经出现过的通过下标的形式存入一个object内。下标的引用要比用indexOf搜索数组快很多。
但是内存占用方面应该第二种方法比较多,因为多了一个hash表。这就是所谓的空间换时间。
Array.prototype.unique2 = function(){ var n = {},r=[]; //n为hash表,r为临时数组 for(var i = 0; i < this.length; i++) //遍历当前数组 { if (!n[this[i]]) { //如果hash表中没有当前项 n[this[i]] = true; //存入hash表 r.push(this[i]); //把当前数组的当前项push到临时数组里面 } } return r; } console.log([1,2,3,'1','2','3',1,2].unique2())
思路3:
先把数组排序,然后比较相邻的两个值。 排序的时候用的JS原生的sort方法,JS引擎内部应该是用的快速排序。
Array.prototype.unique3 = function(){ this.sort(); var re=[this[0]]; for(var i = 1; i < this.length; i++){ if( this[i] !== re[re.length-1]){ re.push(this[i]); } } return re; }
思路4:
利用数组的indexOf方法。此方法的目的是寻找存入参数在数组中第一次出现的位置。
很显然,js引擎在实现这个方法的时候会遍历数组直到找到目标为止。所以此函数会浪费掉很多时间。
Array.prototype.unique4 = function(){ var n = [this[0]]; //结果数组 for(var i = 1; i < this.length; i++) //从第二项开始遍历 { //如果当前数组的第i项在当前数组中第一次出现的位置不是i, //那么表示第i项是重复的,忽略掉。否则存入结果数组 if (this.indexOf(this[i]) == i) n.push(this[i]); } return n; }
//* =============================== 更新新的es5方法 ===========================*//
1、借助栈的方法
let unique = arr => { let res = []; while (arr.length > 0) { let item = arr.shift(); res.indexOf(item) === -1 && res.push(item); } return res; }; console.log(unique([1, 4, 5, 6, 6, 7, 7, 999, 999, 8, 7, 999]));
2、Array from + Set 方法
不考虑兼容性,这种去重的方法代码最少。但是无法去掉“{}”空对象
function unique (arr) { return Array.from(new Set(arr)) } var arr = [1,1,'true','true',true,true,15,15,false,false, undefined,undefined, null,null, NaN, NaN,'NaN', 0, 0, 'a', 'a',{},{}]; console.log(unique(arr)) //[1, "true", true, 15, false, undefined, null, NaN, "NaN", 0, "a", {}, {}]
3、Set 方法
这种去重的方法代码最少。但是set的一个最大的特点就是数据不重复
function unique(arr) { return [...new Set(arr)]; } console.log(unique([1, 2, 2, 3, 4, 4]));
4、indexOf() + lastIndexOf()方法
let unique = arr => { let result = []; arr.forEach((item, index) => { if (arr.indexOf(item, index) === arr.lastIndexOf(item) && result.indexOf(item) === -1) { result.push(item); } }); return result; }; let arr = [1, 4, 5, 6, 6, 7, 7, 999, 999, 8, 7, 999]; console.log(unique(arr));
5、includes()方法
function unique(arr) { let res = []; arr.forEach(item => { if (!res.includes(item)) { res.push(item); } }); return res; } console.log(unique([1, 2, 3, 4, 3, 3, 3, 7, 6, 6, 9, 9]));
6、hasOwnProperty
function unique(arr) { var obj = {}; return arr.filter(function(item, index, arr){ return obj.hasOwnProperty(typeof item + item) ? false : (obj[typeof item + item] = true) }) } var arr = [1,1,'true','true',true,true,15,15,false,false, undefined,undefined, null,null, NaN, NaN,'NaN', 0, 0, 'a', 'a',{},{}]; console.log(unique(arr)) //[1, "true", true, 15, false, undefined, null, NaN, "NaN", 0, "a", {…}] //所有 的都去重了
7、利用reduce+includes
function unique(arr){ return arr.reduce((prev,cur) => prev.includes(cur) ? prev : [...prev,cur], []); } var arr = [1,1,'true','true',true,true,15,15,false,false, undefined,undefined, null,null, NaN, NaN,'NaN', 0, 0, 'a', 'a',{},{}]; console.log(unique(arr)); // [1, "true", true, 15, false, undefined, null, NaN, "NaN", 0, "a", {…}, {…}]
8、利用Map数据结构去重
function arrayNonRepeatfy(arr) { let map = new Map(); let array = new Array(); // 数组用于返回结果 for (let i = 0; i < arr.length; i++) { if(map .has(arr[i])) {// 如果有该key值 map .set(arr[i], true); } else { map .set(arr[i], false); // 如果没有该key值 array .push(arr[i]); } } return array ; } var arr = [1,1,'true','true',true,true,15,15,false,false, undefined,undefined, null,null, NaN, NaN,'NaN', 0, 0, 'a', 'a',{},{}]; console.log(unique(arr)) //[1, "a", "true", true, 15, false, 1, {…}, null, NaN, NaN, "NaN", 0, "a", {…}, undefined]
9、利用filter
function unique(arr) { return arr.filter(function(item, index, arr) { //当前元素,在原始数组中的第一个索引 === 当前索引值,否则返回当前元素 return arr.indexOf(item, 0) === index; }); } var arr = [1,1,'true','true',true,true,15,15,false,false, undefined,undefined, null,null, NaN, NaN,'NaN', 0, 0, 'a', 'a',{},{}]; console.log(unique(arr)) //[1, "true", true, 15, false, undefined, null, "NaN", 0, "a", {…}, {…}]
10、简化map+filter 去重
function unique(arr) { const res = new Map(); //定义常量 res,值为⼀个Map对象实例 //返回arr数组过滤后的结果,结果为⼀个数组 过滤条件是,如果res中没有某个键如no,如没键值就直接arr,就设置这个键的值为1 return arr.filter((arr) => !res.has(arr.no) && res.set(arr.no, 1)) } var arr = [1,1,'true','true',true,true,15,15,false,false, undefined,undefined, null,null, NaN, NaN,'NaN', 0, 0, 'a', 'a',{},{}]; console.log(unique(arr)) //[1, "true", true, 15, false, undefined, null, "NaN", 0, "a", {…}, {…}]