前端面试题笔记-7-数组去重复元素有哪些方法

资料整理自

https://blog.csdn.net/Marker__/article/details/105230882

方法一:双重循环

第i个元素和i之后的元素做比较,不重复则添加进新的数组

 Array.prototype.unique = function() {
      const newArray = []; //要返回出的新数组
      let isRepeat; //当前元素是否重复
      let oldArrayLength = this.length;
      for (let i = 0; i < oldArrayLength; i++) {
          isRepeat=false;
          for (let j = i + 1; j < oldArrayLength; j++) {
              if (this[i] == this[j]) {
                  isRepeat = true;
                  break;
              }
          }
          if (!isRepeat) {
              newArray.push(this[i]);
          }
      }
      return newArray;
  }
  console.log([1, 1, 2, 1, 3, 4, 5, 4].unique())   //[2, 1, 3, 5, 4]

方法二:indexof检测元素

2.1 如果索引不是第一个索引,说明是重复值

Array.prototype.unique = function () {
   return this.filter((item, index) => {
     return this.indexOf(item) === index;    //数组中每个元素的位置(index)和其第一次出现的下标(indexof)对应
   })
 }
 console.log([1,1,2,1,3,4,5,4].unique()); // [1, 2, 3, 4, 5]
  • filter() 方法创建一个新的数组,新数组中的元素是通过检查指定数组中符合条件的所有元素。
其他
  • 关于filter用法
var ages = [32, 33, 16, 40];
function checkAdult(age) {
    return age >= 18;
}

function myFunction() {
    document.getElementById("demo").innerHTML = ages.filter(checkAdult);
}

2.2如果新数组中含有该元素,说明是重复值

Array.prototype.unique = function() {
    const newArray = [];
    this.forEach(item => {
        if (newArray.indexOf(item) === -1) { //如果新数组中不含有当前元素,就push
            newArray.push(item);
        }
    });
    return newArray;
}
console.log([1, 1, 2, 1, 3, 4, 5, 4].unique()); //[1,2,3,4]    

上述的这两种方法输出的数组副本,不会将原数组中的元素出现位置打乱,业界俗称:稳定。

方法三:将原数组用sort()进行排序

3.1 先对原数组进行排序,然后再进行元素比较

Array.prototype.unique = function () {
  const newArray = [];
  this.sort();    //排序
  for (let i = 0; i < this.length; i++) {    //对排序数组进行遍历
    if (this[i] !== this[i + 1]) {    //当前元素和后面的元素不相同就push
      newArray.push(this[i]);
    }
  }
  return newArray;
}

3.2、和新数组的最后一个元素进行比较,如果相同就说明是重复元素。

Array.prototype.unique = function () {
  const newArray = [];
  this.sort();    //排序
  for (let i = 0; i < this.length; i++) {
    if (this[i] !== newArray[newArray.length - 1]) {    //和新数组的最后一个元素比较
      newArray.push(this[i]);
    }
  }
  return newArray;
}

上述的这两种方法由于都用到 sort() 方法, 会打乱原有数组的顺序,所以:不稳定

方法四、检测新数组中元素 includes()

Array.prototype.unique = function () {
  const newArray = [];
  this.forEach(item => {
    if (!newArray.includes(item)) {    //如果新数组中含有当前元素,就说明是重复值
      newArray.push(item);
    }
  });
  return newArray;
}
console.log([1,1,2,1,3,4,5,4].unique());    //[1,2,3,4]    稳定

方法五、配合 sort() 使用 reduce() 去重

Array.prototype.unique = function () {
  return this.sort().reduce((init, current) => {
    if(init.length === 0 || init[init.length - 1] !== current){    //类似于3.2方法
      init.push(current);
    }
    return init;
  }, []);
}                //只要涉及到 sort 方法,就是不稳定的

方法六、Map

  • JavaScript 的对象(Object),本质上是键值对的集合(Hash 结构),但是传统上只能用字符串当作键。这给它的使用带来了很大的限制。为了解决这个问题,ES6 提供了 Map 数据结构。它类似于对象,也是键值对的集合,但是 “键” 的范围不限于字符串,各种类型的值(包括对象)都可以当作键。也就是说,Object 结构提供了 “字符串—值” 的对应,Map 结构提供了 “值—值” 的对应,是一种更完善的 Hash 结构实现。
  • Map 对象保-存键值对,并且能够记住键的原始插入顺序。和 Object 类型不同(key 只能是字符串),在 Map 对象中任何值(对象或者原始值) 都可以作为一个键或一个值。
  • 使用 Map 对象实现数组去重的主要思路:创建一个空 Map,遍历原始数组,把数组的每一个元素作为 key 存到 Map 对象中,因为 Map 中不会出现相同的 key 值,所以最终得到的 Map 中的所有 key 值就是去重后的结果。
function unique(arr) {
  let hashMap = new Map();   //创建一个新的Map对象
  let result = new Array();  // 数组用于返回结果
  for (let i = 0; i < arr.length; i++) {
    if(hashMap.has(arr[i])) {     // 判断 hashMap 中是否已有该 key 值
      hashMap.set(arr[i], true);  // 后面的true 代表该 key 值在原始数组中重复了,false反之
    } else {  // 如果 hashMap 中没有该 key 值,添加
      hashMap.set(arr[i], false);  
      result.push(arr[i]);
    }
  } 
  return result;
}
console.log(unique([1, 1, 1, 2, 3, 3, 4, 5, 5, "a", "b", "a"])); // [ 1, 2, 3, 4, 5, 'a', 'b' ]

方法七、Set

  • Set 对象允许你存储任何类型的 唯一值,无论是原始值或者是对象引用,该方法天生就适合数组去重。

  • NaN 和 undefined 都可以被存储在 Set 中, NaN 之间被视为相同的值(NaN被认为是相同的,尽管 NaN !== NaN)

Array.prototype.unique = function () {
  const set = new Set(this);    //new 一个 Set 对象,将数组作为参数传递进去
  return Array.from(set);       //自动实现去重,Array.from() 将其转化为数组
}                               //可以通过 set.add(args) 添加元素
console.log([1,1,2,1,3,4,5,4].unique());    //[1,2,3,4]    稳定
Array.prototype.unique = function () {
  return [...new Set(this)];    //简化上述步骤
}
console.log([1,1,2,1,3,4,5,4].unique());    //[1,2,3,4]    稳定

你可能感兴趣的:(我的前端面试题-2021)