最近经常面试前端岗位,发现大部分面试官非常愿意考察数组去重的知识,恰好又刷到了几个题,总结一下
题目要求:
- 给定数组去除重复元素,数组元素大多是Number, String类型
- 不能改变原有数组的顺序,去除元素之后保持原有顺序
(一)使用Array.prototype.includes()方法,判断数组中是否有这个元素
function uniteUnique( arr ) { var newarr = []; var uniqueArr = []; // concat(返回一个spreading 的数组) for (var i = 0; i < arguments.length; i++) { // handle the argument object // 不改变顺序的情况下合并为一个大数组; newarr = newarr.concat(arguments[i]); } // 不改变顺序的情况下对数组去重 // 【重点】key:Array.prototype.includes()方法; for (var j = 0; j < newarr.length; j++) {
// 如果不包含这个元素,那么push到数组; if (!uniqueArr.includes(newarr[j])) { uniqueArr.push(newarr[j]); } } return uniqueArr; } console.log(uniteUnique([1, 3, 2], [5, 2, 1, 4], [2, 1]))
(二).使用filter(arrA, arrB)方法,同时使用arrA.indexOf(item)===-1来判断一个item是否在一个数组中,这种方法看起来十分巧妙,是对filter()用法非常熟悉的基础上灵活使用
function uniteUnique(arr1, arr2, arr3) { var newArr; // 把arguments 对象 转成数组,使用Array.prototype.slice.call(argument) var args = Array.prototype.slice.apply(arguments); newArr = args.reduce(function (arrA, arrB) { //【重点】使用filter 方法移除数组中的重复元素 return arrA.concat(arrB.filter( function(i) {
// 如果不包含,则返回true,否则返回false; return arrA.indexOf(i) === -1; })); }); return newArr; } // test here console.log(uniteUnique([1, 3, 2], [5, 2, 1, 4], [2, 1]));
(三)一种特别笨的方法,从学习C++开始就用这种方法,一直对这种方法执念很重,还没有JS函数式编程的思想,就是可以把一个匿名函数传来传去,当然也可能自己对C++一直半解,用不熟函数指针
- 方法就是设置一个flag为true,假设小数组中的所有元素与当前大循环下的这个元素没有相同的。
- 跑两遍循环,首先遍历大数组,不断把不重复的元素填到小数组里,如果有相同的,直接从小循环中跳出来,flag置false;
- 如果小循环跑完了,flag依然为true,那么把大循环中的这个元素插入到小数组中
- 循环跑完,结束
function uniteUnique1(arr1, arr2, arr3) { var newArr; var args = Array.prototype.slice.apply(arguments); // 使用reduce方法拍平数组 newArr = args.reduce(function (arrA, arrB) { // 使用filter 方法移除数组中的duplicate elements; return arrA.concat(arrB); }); 【重点:丑陋地开始了】 var smallArr = []; smallArr.push(newArr[0]); for(var i=0; i<newArr.length; i++){ var flag = true; for(var j=0; j<smallArr.length; j++){ if(newArr[i] == smallArr[j]){ flag = false; break; } } if (flag){ smallArr.push(newArr[i]); } } return smallArr; } // test here console.log(uniteUnique1([1, 3, 2], [5, 2, 1, 4], [2, 1]));
四,2021更新,忽然发现过去的方法是新手,有点繁琐,如果是现在,可以这样
let rmDuplicated = Array.from(new Set([11,11,12,12,1]))