数组去重在前端笔试和面试中出现频率极高,下面为大家总结了常用常见的方法。
//Array.from()写法
function unique(arr) {
return Array.from(new Set(arr));
}
console.log(unique([111,111,"str","str",true,true,undefined,undefined,null,null,NaN,NaN,{},{}]));
//111, "str", true, undefined, null, NaN, {…}, {…}
函数部分可以简写成下面两种
//数组的扩展运算符(...)
function unique(arr) {
return [...new Set(arr)];
}
//箭头函数写法
var unique = (arr) => [...new Set(arr)];
总结:NaN能去重,{}不能去重;
function unique(arr) {
const m = new Map();
return arr.filter(function (item) {
//"&&"遇假返回,若都为真返回最后一个
return !m.has(item) && m.set(item, true);
});
//箭头函数写法
// return arr.filter((item) => !m.has(a) && m.set(item, true));
}
console.log(unique([111, 111, "str", "str", true, true, undefined, undefined, null, null, NaN, NaN, {}, {}]))
//111, "str", true, undefined, null, NaN, {…}, {…}
总结:NaN能去重,{}不能去重;
function unique(arr){
for(var i=0; i<arr.length; i++){
for(var j=i+1; j<arr.length; j++){
if(arr[i]===arr[j]){//若相同,调用splice()方法删除第二个
arr.splice(j,1);
j--;
}
}
}
return arr;
}
console.log(unique([111,111,"str","str",true,true,undefined,undefined,null,null,NaN,NaN,{},{}]));
//111, "str", true, undefined, null, NaN, NaN, {…}, {…}
function unique(arr) {
// newArr用来存储结果
var newArr = [];
for (var i = 0; i < arr.length; i++) {
for (var j = 0; j < newArr.length; j++ ) {
if (arr[i] === newArr[j]) {
break;
}
}
// 如果arr[i]是唯一的,那么执行完循环,j等于newArr.length
if (j === newArr.length) {
newArr.push(arr[i])
}
}
return newArr;
}
console.log(unique([111,111,"str","str",true,true,undefined,undefined,null,null,NaN,NaN,{},{}]));
//111, "str", true, undefined, null, NaN, NaN, {…}, {…}
总结:两种方法结果都是一样,本质通过遍历对数组每一项进行三等判断,此方法NaN和{}不能去重。注意,若进行的是双等判断,会直接将所有null删除。
利用indexOf简化内层循环,判断新数组中是否存在了当前元素,不存在则通过push()方法将当前元素追加到新数组中。
function unique(arr) {
//newArr用来储存数据
var newArr = [];
for (var i = 0; i < arr.length; i++) {
if (newArr.indexOf(arr[i]) === -1) {
newArr.push(arr[i]);
}
}
return newArr;
}
console.log(unique([111, 111, "str", "str", true, true, undefined, undefined, null, null, NaN, NaN, {}, {}]));
//111, "str", true, undefined, null, NaN, NaN, {…}, {…}
总结:此方法NaN和{}不能去重
利用数字的sort()方法先对数组进行排序,这样重复项就变成了相邻项,我们只需判断数组当前项是否与前一项相同即可,不同则利用push()方法追加到新数组中。
function unique(arr) {
arr = arr.sort();
var newArr = [arr[0]];//用newArr来储存数据,并先将arr[0]存在数组中
for (var i = 1; i < arr.length; i++) {//i从1开始
if (arr[i] !== arr[i - 1]) {//判断当前项是否等于前一项
newArr.push(arr[i]);
}
}
return newArr;
}
console.log(unique([111, 111, "str", "str", true, true, undefined, undefined, null, null, NaN, NaN, {}, {}]));
//111, NaN, NaN, {…}, {…}, null, "str", true, undefined
function unique(arr) {
arr = arr.sort();
var newArr = [];//newArr用来储存数据
var temp;//temp用来储存前一项
for (var i = 0; i < arr.length; i++) {//i从0开始
if (!i || temp !== arr[i]) {//判断当前项是否等于前一项
newArr.push(arr[i]);
}
temp = arr[i];
}
return newArr;
}
console.log(unique([111, 111, "str", "str", true, true, undefined, undefined, null, null, NaN, NaN, {}, {}]));
//111, NaN, NaN, {…}, {…}, null, "str", true, undefined
总结:此方法比起indexOf效率高,NaN和{}不能去重
filter()返回原始数组中执行callback函数后为true的项,不满足会直接跳过,filter()不会改变原始数组。
function unique(arr) {
return arr.filter(function (item, index, arr) {
//过滤条件:当前元素,在原始数组中的第一个索引==当前索引值,否则返回当前元素
return arr.indexOf(item) === index;
});
}
console.log(unique([111, 111, "str", "str", true, true, undefined, undefined, null, null, NaN, NaN, {}, {}]));
//111, "str", true, undefined, null, {…}, {…}
function unique(arr) {
return arr.sort().filter(function(item, index, arr){
//判断数组当前项和前一项是否相等,不等为true
return !index || item !== arr[index - 1];
});
}
console.log(unique([111, 111, "str", "str", true, true, undefined, undefined, null, null, NaN, NaN, {}, {}]));
//111, NaN, NaN, {…}, {…}, null, "str", true, undefined
总结:使用filter()+indexOf(),所有的NaN会直接被删除,{}不能去重;使用filter()+sort()NaN和{}不能去重。
includes()方法可以判断数组是否包含指定的值,遍历原始数组判断新数组中是否包含原始数组中的每一项,不包含则使用push()方法追加到新数组中。
function unique(arr) {
var newArr = [];//newArr用来储存数据
for (var i = 0; i < arr.length; i++) {
if (!newArr.includes(arr[i])) {
newArr.push(arr[i]);
}
}
return newArr;
}
console.log(unique([111, 111, "str", "str", true, true, undefined, undefined, null, null, NaN, NaN, {}, {}]));
//111, "str", true, undefined, null, NaN, {…}, {…}
总结:此方法NaN能去重,{}不能去重
我们定义一个空的 Object 对象,利用hasOwnProperty()方法判断对象是否存在该属性,不存在则添加,存在则跳过,比如有 Object[key1] = true,在判断另一个值的时候,如果 Object[key2]存在的话,就说明该值是重复的。
function unique(arr) {
var obj = {};
return arr.filter(function(item, index, arr){
//假如我们认为数字和其该数字的数字字符串是不同的,则需让(typeof item + item)整体作为Object的key
return obj.hasOwnProperty(typeof item + item) ? false : (obj[typeof item + item] = true)
});
}
console.log(unique([111, 111, "str", "str", true, true, undefined, undefined, null, null, NaN, NaN, {}, {}]));
//111, "str", true, undefined, null, NaN, {…}
若将对象obj申明在全局,最后我们再输出,可以清楚的看到里面的属性和值
总结:几乎所有都能去重
笔者是一个js初学者,欢迎各位大佬对内容进行指点。