js面试题总结(1)— 数组去重的方法

150 阅读2分钟

数组去重的方法

数组去重的方法总结:

  1. 循环遍历push进新数组
  2. 直接使用splice在原数组上进行操作
  3. 对象键值对法
  4. 排序后相邻去除法
  5. ES6新方法 Set去重(亮点)
  6. 利用filter方法去重
  7. 递归去重法(需要利用sort排序)
  8. 利用reduce去重
  9. 利用Map构造函数去重

①循环遍历push进新数组

先定义一个空数组,然后遍历原数组,若新数组中没有一样的值,那么把元素push进新数组。

var arr = [1, 1, 2, 2, 3, 3, 4, 4, 5, 5];
var temp=[];
for(var i = 0; i< arr.length; i++){
    if(temp.indexOf(arr[i]) === -1){
        temp.push(arr[i]);
    }
}

console.log(temp); // [1, 2, 3, 4, 5]

特点:最简单的数组去重方法

②直接使用splice在原数组上进行操作

直接遍历数组,判断(indexOf)当前元素在数组中首次出现的下标,若之前出现过,则使用splice删除当前元素。

var arr = [1, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5];
for(var i = 0; i < arr.length; i++) {
    if(arr.indexOf(arr[i]) !== i){
        arr.splice(i, 1);
        i--;
    }
}

console.log(arr); // [1, 2, 3, 4, 5]

特点:简单易懂,但占用内存高,速度慢

③对象键值对法

利用对象的属性不能相同的特点,创建一个空对象,创建一个空数组,遍历原数组,创建两个变量分别存储,元素值和元素的类型,如果对象上不存在key为元素值的属性,那么将元素值push进新数组,对象上存上key值元素值,value为一个数组(数组上存着元素类型)的键值对,如果元素值和key值相同,而value上没有相同的类型,那么把元素类型push到value上的数组,并且也将元素值push进新数组,最终输出新数组。

var arr = [1, 1, 2, 2, 3, 3, 4, 4, 5, 5, "2", "2", "3", "3"];
var temp = {}, r = [], val, type;
for(var i = 0; i < arr.length; i++){
    var val = arr[i];
    var type = typeof val;
    if(!temp[val]) {
        temp[val] = [type];
        r.push(val)
    } else if (temp[val].indexOf(type) < 0) {
        temp[val].push(type);
        r.push(val)
    }
}
console.log(temp); 
/*
{ 
    1: ['number'],
    2: ['number', 'string'],
    3: ['number', 'string'],
    4: ['number'],
    5: ['number']
}
*/

console.log(r); // [1, 2, 3, 4, 5, '2', '3']

特点:相对来说最快的一种去重方法,但是占用的内存大一些

④排序后相邻去除法

先用sort排序,然后创建一个空数组,将原数组的第一个值放入空数组中,for循环遍历原数组,若元素不等于新数组中的最后一个值,则把元素push进数组。

var arr = [1, 2, 3, 4, 5, 1, 2, 3, 4, 5];
arr.sort()
var temp = [arr[0]]
for(var i = 1; i < arr.length; i++){
    if(arr[i] !== temp[temp.length - 1]){
        temp.push(arr[i])
    }
}

console.log(temp); // [1, 2, 3, 4, 5]

特点:和循环遍历push新数组的方法类似

⑤ES6新方法 Set去重(亮点)

利用ES6新特性,Set构造函数,new Set() 将原数组传进去,Set方法将返回一个没有重复value值的对象,再通过...将对象解构放入数组中

var arr = [1, 2, 3, 4, 5, 1, 2, 3, 4, 5];
var temp = new Set(arr)
console.log(temp)
console.log([...temp]) // [1, 2, 3, 4, 5]

temp对象的结构和值

image.png

特点:ES6新语法 代码精简

⑥利用filter方法去重

利用filter方法,过滤出元素的索引值和当前元素值第一出现的位置的索引值相等的元素,并使用一个变量接收。(注意:filter过滤不会改变原数组,但是会返回一个新数组)

var arr = [1, 2, 3, 4, 5, 1, 2, 3, 4, 5];
var temp = arr.filter((item, index, arr) => arr.indexOf(item) === index)
console.log(temp) // [1, 2, 3, 4, 5]

特点:代码精简

⑦递归去重法(需要利用sort排序)

先将原数组排序,然后定义一个函数,接收一个代表索引的参数,从最后开始比较,如果最后一个元素值和倒数第二个元素的值相等,则删除最后一个元素,然后继续调用此函数,以此类推。

var arr = [1, 2, 3, 4, 5, 1, 2, 3, 4, 5];
arr.sort()
function loop(index){
    if(index >= 1){
        if(arr[index] === arr[index - 1]) {
            arr.splice(index, 1)
        }
        loop(index - 1)
    }
}

loop(arr.length - 1)

console.log(arr) // [1, 2, 3, 4, 5]

特点:使用递归的方法

⑧利用reduce去重

利用reduce,给reduce传入一个函数,函数接收两个参数,一个表示上次回调时的返回值(为一个数组)(或者初始值[ ]),一个表示当前正在处理的数组元素,初始值为一个空数组,若返回的数组中没有当前元素值,那么将此元素添加进去返回新数组,若有当前值,则返回之前的数组,最后使用一个变量接收。(注意:reduce不改变原数组,但会返回一个新数组)

var arr = [1, 2, 3, 4, 5, 1, 2, 3, 4, 5];
var temp = arr.reduce((prev, cur) => prev.indexOf(cur) === -1 ? [...prev, cur] : prev, [])
console.log(temp) // [1, 2, 3, 4, 5]

特点:使用reduce方法

⑨利用Map构造函数去重

创建一个空Map数据结构,创建一个空数组,遍历原数组,利用Map构造函数上的has方法判断是否已存在,若不存在,则利用set方法(向实例对象上添加或更新一个key),将元素值添加到实例对象的key上,并且将元素值放入新数组中

var arr = [1, 2, 3, 4, 5, 1, 2, 3, 4, 5];
var map = new Map()
var temp = []
for(var i = 0; i < arr.length; i++){
    if(!map.has(arr[i])){
        map.set(arr[i])
        temp.push(arr[i])
    }
}

console.log(temp) // [1, 2, 3, 4, 5]

特点:使用了Map构造函数