面题系列:数组去重

131 阅读2分钟

Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情

题目描述

我们在开发中最常用的数据结构莫过于数组了,现在有一组数组数据,希望你可以把其中的重复项清除掉,你有什么好的方案吗?可以说出几种来吗?

考察点

  1. ES6 set的了解和使用
  2. JS Array API 的了解和使用
  3. JS 遍历的操作基础

解题思路

数组转set

ES6的新增的数据结构,它类似于数组,但是成员的值都是唯一的,没有重复的值。所以,如果将数组转化成是set的时候,再转回数组,也就意味着他会自动把重复的去除掉,然后又变成了数组结构,十分的简单方便。

// 法1: Array.from转化
const arr = Array.from
Array.from(new Set(["0", 0, 1, 1, null, null]))
// arr => ['0', 0, 1, null]
// 法2: ...扩展转化
const arr = [...new Set(["0", 0, 1, 1, null, null])];
// arr => ['0', 0, 1, null]

双循环标记遍历

这是一种最简单,最符合人类正常思维的一种方法,就是创建新数组,双循环用标记遍历数据记录存不存在,存在就不会存储到新数组中,不存在就存起来,但是复杂度和空间复杂度都很高,不适用于大型数组的去重任务。

const arr = ["0", 0, 1, 1, null, null];

function unique(arr) {
    let list = [arr[0]];
    for (let i = 1,len = arr.length; i < len; i++) {
        let flag = true
        for (let j = 0; j < len - 1; j++) {
            if (arr[i] === list[j]) {
                flag = false;
                break
            }
        }
        if (flag) list.push(arr[i])
    }
    return list
}

// unique(arr) => ['0', 0, 1, null]

filter过滤去重

filter()是数组的高阶API,完成过滤任务,配合indexOf方法,来判断都数组是否有相同坐标值,坐标相同的留下,不相同的过滤掉(坐标值不相同意味着出现过),这样来做去重任务,操作非常的简单方便,但是filter()其执行效率却并不是那么的高效。

const arr = ["0", 0, 1, 1, null, null];

function unique(arr) {
    return Array.prototype.filter.call(arr,(item, index) => arr.indexOf(item) === index)
}

// unique(arr) => ['0', 0, 1, null]

相邻元素去重

sort()也是数组的高阶API,它用原地算法对数组的元素进行排序,并返回数组。默认排序顺序是在将元素转换为字符串,然后比较它们的UTF-16代码单元值序列时构建的。利用它将相近的数据可以排列出来,然后经过一次循环遍历,去查找他上一个值是否相等,如果不相等就存储到新数组中,来实现去重任务。

const arr = ["0", 0, 1, 1, null, null];

function unique(arr) {
    let _arr = arr.sort()
    let list = []
    for (let i = 0; i < _arr.length; i++) {
        if (_arr[i] !== _arr[i-1]) {
            list.push(_arr[i])
        }
    }
    return list
}

// unique(arr) => ['0', 0, 1, null]