在开发和面试中总是或多或少会提及数组去重问题,今天特意花时间整理了一下,涉及到基本数据类型数组去重及对象数组去重。
let arr = [1,'a',true,undefined,1,{},NaN,null,{'a':'1','b': '3'},true,NaN,'a',undefined,{'a':'1','b': '2'},,null,{},{'a':'1','b': '2'}]; // 1. 使用for循环加indexOf()去重 // 缺陷:只适用于基本数据类型数组去重,且无法对NaN进行去重,原因:arr.indexOf(NaN)返回值总为-1 function unique1(arr) { let resultArr = []; for (let i = 0; i < arr.length; i++) { if(resultArr.indexOf(arr[i]) < 0) { resultArr.push(arr[i]); } } // console.log(resultArr,'1'); return resultArr; } // 2. 利用ES6中的set数据类型和Array.from()方法去重 // 缺陷:只适用于基本数据类型数组去重 function unique2(arr) { // console.log(Array.from(new Set(arr)),'2'); return Array.from(new Set(arr)); // 或者如下: // return [...new Set(arr)]; } // 3. 利用ES6中的map方法去重 // 只适用于基本数据类型数组去重 function unique3(arr) { let map = new Map(); let resultArr = []; for (let i = 0; i < arr.length; i++) { if(!map.has(arr[i])) { map.set(arr[i], true); resultArr.push(arr[i]); } } // console.log(resultArr,'3'); return resultArr; } // 4. 利用filter方法去重 // 原理:根据元素当前所在下标是否为元素第一次出现下标做对比判断是否重复 // 缺陷:只适用于基本数据类型数组去重,且会丢失NaN数据,原因:arr.indexOf(NaN)返回值总为-1 function unique4(arr) { let resultArr = arr.filter((item, index, arr) => { return arr.indexOf(item) === index; }) // console.log(resultArr,'4'); return resultArr; } // 5. 借助ES6中的Array.includes()方法去重 // Array.includes():判断某数组中是否包含指定值,返回一个boolean值 // 缺陷:只适用于基本数据类型数组去重 function unique5(arr) { let resultArr = []; arr.forEach(item => { if(!resultArr.includes(item)) { resultArr.push(item); } }); // console.log(resultArr, '5'); return resultArr; } // 6. 利用Array.reduce()和Array.includes()方法结合去重 // Array.reduce(回调函数,初始值): 接受一个函数作为累加器,其中prev参数为上一次累加结果 // [...prev,cur]:ES6新增的数组扩展运算符,类似于将cur元素插入到原有的prev数组后面 // 缺陷:只适用于基本数据类型数组去重 function unique6(arr) { let resultArr = arr.reduce((prev,cur,index,array) => { return prev.includes(cur) ? prev : [...prev,cur]; }, []); // console.log(resultArr, '6'); return resultArr; } // 对象数组去重 -- 对象型数组去重需具体业务逻辑具体分析 let arr2 = [{ id: '01', name: '乐乐' }, { id: '02', name: '博博' }, { id: '01', name: '乐乐2' }, { id: '03', name: '淘淘' }, { id: '04', name: '哈哈' }, { id: '01', name: '乐乐' }, { id: '05', name: '乐乐' }]; unique9(arr2); // 1. 利用对象访问属性的方法,判断对象中是否存在key function unique7(arr) { let resultArr = []; let obj = {}; arr.forEach(item => { let key = item.id + item.name; // 以每一个对象中的id+name作为key来判断是否存在,过滤掉数组中id+name相同的对象 if(!obj[key]) { resultArr.push(item); obj[key] = true; } }); // console.log(resultArr, '7'); return resultArr; } // 2. 利用map类型去重,原理同上述方法1 function unique8(arr) { let map = new Map(); let resultArr = []; arr.forEach(item => { let key = item.name; // 以每一个对象中的name作为key来判断是否存在,过滤掉数组中name相同的对象 if(!map.has(key)) { resultArr.push(item); map.set(key, true); } }); // console.log(resultArr, '8'); return resultArr; } // 3. 利用Array.reduce()累加器方法去重,原理同上述方法1 function unique9(arr) { let obj = {}; let resultArr = arr.reduce((prev,cur) => { // 以每一个对象中的id作为key来判断是否存在,过滤掉数组中id相同的对象 obj[cur.id] ? '' : prev.push(cur) && (obj[cur.id] = true); return prev; }, []); // console.log(resultArr, '9'); return resultArr; }