数组去重

数组去重

数组去重一直是我们老生常谈的东西了,但是真正的让我们对某个数组去重,我们是不是能毫无畏惧呢,哈哈哈。来让我们一起来看看这个东西,达成一个新的成就点吧。😉

什么是数组去重

俗话说,知己知彼,我们才能百战百胜。我们在对一个数组进行去重之前我们要知道数组去重到底是什么。

好,那现在就来好(hu)好(bian)说(luan)下(zao)啊,这个数组去重啊,其实就是。。。😜


数组去重。

好了,正经起来。其实数组去重,就是将一列数组进行去重,顾名思义,数组中可能有很多重复的元素,我们将这些重复的元素删去,这个过程就是数组去重。

数组去重的方法

我反复查看了好多大佬的博客,他们写了好多好多种方法,看起来牛X轰轰的,但是我仔细一看,其实这就是两种法子,暴力和非暴力嘛。哎,我自己总结一下吧,心累累。😓

暴力解法

暴力解法1(splice删除法)

别看是暴力方法,其实这个是我们最为常用的方法呢🙄

思路

进行两层循环遍历,将每一个元素进行两两对比,发现有相同的就删除元素。

var arr = [1, 1, 'true', 'true', true, true, 15, 15, false, false, undefined, undefined, null, null, NaN, NaN, 'NaN', 0, 0, 'a', 'a', {}, {}];
for (let i = 0; i < arr.length; i++) {
    for (let j = i + 1; j < arr.length; j++) {
        if (arr[i] == arr[j]) {
            arr.splice(j, 1);
            j--;
        }
    }
}
console.log(arr.valueOf());//[1,'true', false,undefined, NaN, NaN,'NaN','a',{},{}]

特点
  1. 两次循环导致,时间复杂度为O(N^2)
  2. 使用有局限性,无法对特别的元素进行去重,比如NaN无法去重,null则直接消失,对象也无法去重。
暴力解法2(无脑排序法)

这个方法是我一直都使用的方法,所以写在这,手动捂脸。

思路

结合额外的,进行排序之后一层循环比较前后两个元素是否相等,然后进行去重。

var arr = [1, 1, 'true', 'true', true, true, 15, 15, false, false, undefined, undefined, null, null, NaN, NaN, 'NaN', 0, 0, 'a', 'a', {}, {}];
arr.sort();
var array = [];
for (let i = 0; i < arr.length; i++) {
    if (arr[i] != arr[i - 1]) {
        array.push(arr[i])
    }
}
console.log(array.valueOf())//[1,'true', false,undefined, NaN, NaN,'NaN','a',{},{}]
特点

其实就和上面的差不多,也是无法对那些特别的(无法进行数值比较的)元素进行去重。

暴力解法3(indexOf
思路

结合,无需排序即可达到去重的目的。indexOf()方法来判断是否存在元素相同

var arr = [1, 1, 'true', 'true', true, true, 15, 15, false, false, undefined, undefined, null, null, NaN, NaN, 'NaN', 0, 0, 'a', 'a', {}, {}];
var array = [];
for (let i = 0; i < arr.length; i++) {
    //判断我们遍历到的元素是否存在于我们使用的栈数组中
    if (array.indexOf(arr[i]) === -1) {
        array.push(arr[i]);
    }
}
console.log(array.valueOf())
特点
  • 这个方法无法对特别的元素进行去重
  • 增加了空间复杂度
暴力解法4(includes
思路

结合,无需排序即可达到去重的目的。includes()方法来判断是否存在元素相同

var arr = [1, 1, 'true', 'true', true, true, 15, 15, false, false, undefined, undefined, null, null, NaN, NaN, 'NaN', 0, 0, 'a', 'a', {}, {}];
var array = [];
for (let i = 0; i < arr.length; i++) {
        //判断我们遍历到的元素是否存在于我们使用的栈数组中
    if (array.indexOf(arr[i]) === -1) {
        array.push(arr[i]);
    }
}
console.log(array.valueOf())
特点

使用了数组的includes方法,换汤不换药思路与上面的基本相同

暴力解法5(数组的处理函数)

数组有几个方法,可以让我们更方便的对数组进行操作。

filter,reducemap

function unique(arr) {
    return arr.filter(function(item, index, arr) {
        //当前元素,在原始数组中的第一个索引==当前索引值,否则返回当前元素
        return arr.indexOf(item) === index;
    });
}
var 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))
function unique(arr) {
    return arr.reduce((prev, cur) => prev.includes(cur) ? prev : [...prev, cur], []);
}
var 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)); 
特点

不想说了,和前面都是一样的,没啥说的。

暴力解法6(递归法)

PS:我觉得这种办法时间复杂度很高啊,不知道为什么有的博主把这个放在这里将,感觉没啥用,还不如前面的哈哈哈。

function unique(arr) {
    var array = arr;
    var len = array.length;

    array.sort(function(a, b) { //排序后更加方便去重
        return a - b;
    })

    function loop(index) {
        if (index >= 1) {
            if (array[index] === array[index - 1]) {
                array.splice(index, 1);
            }
            loop(index - 1); //递归loop,然后数组去重
        }
    }
    loop(len - 1);
    return array;
}
var 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))

各位看官康康就行,嘻嘻嘻

投机取巧法

Set数据类型

我们都知道Set数据类型有一个特点,就是其中的数据是不重复的,我们正好可以利用这一特点,让我们的数组去重变得简单。

ES6数组拓展符(…)
var arr = [1, 1, 'true', 'true', true, true, 15, 15, false, false, undefined, undefined, null, null, NaN, NaN, 'NaN', 0, 0, 'a', 'a', {}, {}];
console.log([...new Set(arr)]);
特点
  1. 利用了Set数据类型的特点,达到去重的目的
  2. 这种方法依旧无法对空对象进行去重
Map数据类型
思路

哈希表的特点就是存储的每一个元素都有键值对,那么我们遍历数组的时候给每一个元素都进行标记,那么下次访问到新的元素的时候只需要判断一下是否访问过即可。

function unique(arr) {
    let map = new Map();
    let array = new Array(); // 数组用于返回结果
    for (let i = 0; i < arr.length; i++) {
        if (map.has(arr[i])) { // 如果有该key值
            map.set(arr[i], true);
        } else {
            map.set(arr[i], false); // 如果没有该key值
            array.push(arr[i]);
        }
    }
    return array;
}
var 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))
特点
  • 无法对空对象进行去重
对象利用法

唉看这个名字就知道这个方法很不好,利用对象,唉,罪过。言归正传~

此对象非彼对象,我们都知道对象的属性是不可以重复的,啊,灵光一闪。那么我们就可以利用这个特点,将数组去重,机智的’‘小天才’’。

思路

先创建一个新对象,然后使用数组的方法,进行遍历选择,如果在对象中没有属性的话,我们就将其设置为true,否则就是false.

返回即可去重,利用的就是对象的属性的唯一性。

var arr = [1, 1, 'true', 'true', true, true, 15, 15, false, false, undefined, undefined, null, null, NaN, NaN, 'NaN', 0, 0, 'a', 'a', {}, {}];

function unique(arr) {
    var obj = {};
    return arr.filter((item, index, arr) => {
        return obj.hasOwnProperty(typeof item + item) ? false : (obj[typeof item + item] = true)

    })
}
console.log(unique(arr));
特点

个人感觉这是目前最完美的数组去重方法了,它可以将所有的元素一一去重。建议大家多多使用。(๑•̀ㅂ•́)و✧

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值