方法1:新数组+for循环+indexOf
创建新数组,将需要去重的数组的元素一个个放进去,新数组中已经存在了的元素就不要放了,最后返回新数组
Array.prototype.unique = function(){
let arr = []
for(let i = 0;i< this.length;i++){
if(arr.indexOf(this[i]) == -1){
arr.push(this[i])
}
}
return arr
}
let arr = [1,1,'true','true',true,true,15,15,false,false, undefined,undefined, null,null, NaN, NaN,'NaN', 0, 0, 'a', 'a',{},{}];
console.log(arr.unique())
// [1, "true", true, 15, false, undefined, null, NaN, NaN, "NaN", 0, "a", {…}, {…}]
//NaN、{}没有去重
方法2:indexOf+filter
过滤数组元素,当一个元素第一次出现的索引等于当前索引时,返回该元素
Array.prototype.unique = function () {
return this.filter((item, index, arr) => {
return arr.indexOf(item) === index;
});
};
let arr = [1,1,'true','true',true,true,15,15,false,false, undefined,undefined, null,null, NaN, NaN,'NaN', 0, 0, 'a', 'a',{},{}];
console.log(arr.unique())
//[1, "true", true, 15, false, undefined, null, "NaN", 0, "a", {…}, {…}]
//两个NaN没有了,{}没有去重
方法3:新数组+includes
includes判断一个数组中是否包含一个指定的值,根据情况,如果包含则返回true,否则返回false
Array.prototype.unique = function () {
let arr = [];
for (let i = 0; i < this.length; i++) {
if (!arr.includes(this[i])) {
arr.push(this[i]);
}
}
return arr;
};
let arr = [1,1,'true','true',true,true,15,15,false,false, undefined,undefined, null,null, NaN, NaN,'NaN', 0, 0, 'a', 'a',{},{}];
console.log(arr.unique())
//[1, "true", true, 15, false, undefined, null, NaN, "NaN", 0, "a", {…}, {…}]
//{}没有去重
方法4:对象
创建对象和新数组,将需要去重的数组的元素作为对象的属性名一个个添加给对象,属性名没有对应的值说明这个元素第一次出现,将属性名放入新数组,并给它赋值作为标记,属性名有对应的值说明这个元素已经重复,跳过,最后返回新数组
Array.prototype.unique = function(){
var temp = {},
arr = [],
len = this.length
for(var i = 0;i < len;i ++ ){
if(!temp[this[i]]){
temp[this[i]] = 1
arr.push(this[i])
}
}
return arr
}
let 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", 15, false, undefined, null, NaN, 0, "a", {…}]
//两个true直接去掉了,NaN和{}去重
方法5:ES6的Set方法
重复元素在Set方法中会自动被过滤
function unique (arr) {
//Array.from()方法可对一个类似数组或可迭代对象创建一个新的,浅拷贝的数组实例
return Array.from(new Set(arr))
//return [...new Set(arr)]
}
let arr = [1,1,'true','true',true,true,15,15,false,false, undefined,undefined, null,null, NaN, NaN,'NaN', 0, 0, 'a', 'a',{},{},{a:1},{a:1}];
console.log(arr.unique())
//[1, "true", true, 15, false, undefined, null, NaN, "NaN", 0, "a", {}, {}, {a:1}, {a:1}]
//{}没有去重
Array.from
方法对一个类似数组或可迭代对象创建一个新的、浅拷贝的数组实例
方法6:对象+hasOwnProperty + filter
hasOwnProperty 判断是否存在对象自有属性,不会找到原型链上的继承属性
function unique(arr) {
let obj = {};
return arr.filter(function(item, index, arr){
return obj.hasOwnProperty(typeof item + item) ? false : (obj[typeof item + item] = true)
})
}
let arr = [1,1,'true','true',true,true,15,15,false,false, undefined,undefined, null,null, NaN, NaN,'NaN', 0, 0, 'a', 'a',{},{}];
console.log(arr.unique())
//[1, "true", true, 15, false, undefined, null, NaN, "NaN", 0, "a", {…}] //所有的都去重了
方法7:双重for嵌套+splice
Array.prototype.unique = function () {
for (let i = 0; i < this.length; i++) {
for (let j = i + 1; j < this.length; j++) {
if (this[i] == this[j]) {
arr.splice(j, 1);
j--;
}
}
}
return arr;
};
let arr = [1,1,'true','true',true,true,15,15,false,false, undefined,undefined, null,null, NaN, NaN,'NaN', 0, 0, 'a', 'a',{},{}];
console.log(arr.unique())
//[1, "true", 15, false, undefined, NaN, NaN, "NaN", "a", {…}, {…}]
//NaN和{}没有去重,两个null直接消失了
方法8:sort()
sort()排序,根据排序后的结果遍历数组,和相邻元素比对
Array.prototype.unique = function () {
let arr = this.sort();
let target = [arr[0]];
for (let i = 1; i < arr.length; i++) {
if (arr[i] !== arr[i - 1]) {
target.push(arr[i]);
}
}
return target;
};
let arr = [1,1,'true','true',true,true,15,15,false,false, undefined,undefined, null,null, NaN, NaN,'NaN', 0, 0, 'a', 'a',{},{}];
console.log(arr.unique())
//[0, 1, 15, NaN, NaN, "NaN", {…}, {…}, "a", false, null, "true", true, undefined]
//NaN和{}没有去重
方法9:sort+递归函数(原理和纯sort方法类似)
Array.prototype.unique = function () {
let arr = this.sort();//排序后去重更加方便
let len = arr.length;
function loop(index = 0) {
if (arr[index] == arr[index + 1]) {
arr.splice(index, 1);//相同元素踢出去
}
if (index + 1 == len) return;
loop(index + 1);
}
loop();
return arr;
};
let arr = [1,1,'true','true',true,true,15,15,false,false, undefined,undefined, null,null, NaN, NaN,'NaN', 0, 0, 'a', 'a',{},{}];
console.log(arr.unique())
//[0, 1, 15, NaN, NaN, "NaN", {…}, {…}, "a", false, null, "true", true, undefined]
//NaN和{}没有去重
方法10:Map数据结构
把数组的元素作为key值存到Map中,Map中不会出现相同的key值
Array.prototype.unique = function () {
let map = new Map();
let target = [];
this.forEach((item, index) => {
if (!map.has(item)) {
target.push(item);
map.set(item, true);
}
});
return target;
};
let arr = [1,1,'true','true',true,true,15,15,false,false, undefined,undefined, null,null, NaN, NaN,'NaN', 0, 0, 'a', 'a',{},{}];
console.log(arr.unique())
//[1, "true", true, 15, false, undefined, null, NaN, "NaN", 0, "a", {…}, {…}]
//{}没有去重
方法11:reduce+includes
数组的reduce方法和迭代方法map、filter、forEach一样,会遍历数组,reduce()方法会遍历数组中的每一个元素,每遍历一次就会执行一次回调函数,遍历完后会将最后的结果返回出去
reduce方法有两个参数,第一个参数是累加函数,第二个参数是累加函数中previousValue的初始值。
累加函数有四个参数,分别是:previousValue、nowValue、nowIndex、arr,其中后两个参数为可选参数
Array.prototype.unique = function () {
return this.reduce(
(prev, cur) => (prev.includes(cur) ? prev : [...prev, cur]),
[]
);
};
let arr = [1,1,'true','true',true,true,15,15,false,false, undefined,undefined, null,null, NaN, NaN,'NaN', 0, 0, 'a', 'a',{},{}];
console.log(arr.unique())
// [1, "true", true, 15, false, undefined, null, NaN, "NaN", 0, "a", {…}, {…}]
//{}没有去重