JS数组去重 代码实现

方法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", {…}, {…}]
//{}没有去重
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值