JS数组去重的方法

几乎每个面试官都要问的数组去重的方法

有一位面试官有提醒我,数组内可能还会嵌套数组或者对象,数组内的元素类型可能也不尽相同,希望大家在实际操作中可以考虑到这些情况。

var arr = ['1','2',3, 2, 2, 4, 4, 4];

1 最简单的方法: Set

Array.prototype.distinct = function(){
    return [...new Set(this)];
}

MDN:
Set 对象允许你存储任何类型的唯一值,无论是原始值或者是对象引用。
语法:new Set([iterable]);

注意它返回的是一个Set对象,所以在处理数组的时候用…拆分再组装成一个新数组对象。

Set 的计算法则和 === 是不同的

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

解释一下这里的 iterable:
MDN Reference

for of 语句可以遍历的 iterable 对象包括:String,Array,类Array(arguments或NodeList),TypedArray,Map, Set,还有用户自定义的 iterables。

这里面还包括了generator函数…可以查看reference中的案例

for of语句主要是遍历的对象的值value,相对于for in遍历的是对象的key。

这里不多赘述,可以查看JS数组遍历方法详解。

Set方法和属性

Set.prototype.size:对象的值的个数(Set.length 为 0)

方法:

  • Set.add(value): 返回Set对象
  • Set.clear() 移除所有元素
  • Set.delete(value) : 返回 Set.prototype.has(value)
  • Set.prototype.entries():把value变为数组的形式。entries是一个数组,每个元素是Set的key+value组成的数组,为了和map的形式对应,把Set的key设为和Value等值的元素。见下文代码
  • Set.prototype.forEach(callbackFn[, thisArg]): 给Set每个元素调用callback函数,this表示context
  • Set.prototype.has(value) 返回boolean 表示value是否存在
  • Set.prototype.keys() 与values()方法相同
  • Set.prototype.values()
// Set.prototype.entries()
const set1 = new Set();
set1.add(42);
set1.add('forty two');

const iterator1 = set1.entries();

for (let entry of iterator1) {
  console.log(entry);
  // expected output: [42, 42]
  // expected output: ["forty two", "forty two"]
}

//求交集
// intersect can be simulated via 
var intersection = new Set([...set1].filter(x => set2.has(x)));
//求差集
// difference can be simulated via
var difference = new Set([...set1].filter(x => !set2.has(x)));

2 map对象储存

存放在map对象中。key为type+item,value为item,从而避免同类型的数据难以区分的问题

Array.prototype.distinct = function(){  

    let arr_map = {};
    let result = [];

    //遍历数组,储存到map中
    arr.forEach(item => {
        let key = typeof(item)+'_'+item;
        arr_map[key] = item;
    }); 

    //map的value保存为数组
    Object.keys(arr_map).forEach( item => {
        let val = arr_map[item];
        result.push(val);
    });

    return result;
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值