数组去重,很多时候都会用到,在具体项目中因为场景确定,很容易写出一个简单的去重方法,但大多是否具有针对性,没法适用于各类,一劳永逸。
当然此处的场景所说的去重指的是去除内容大致相同的数据,不管是否同一个引用
。
如下这段代码,如果希望输出的是 [[1],{a:2},{a:1},[2]]
let obj = {a:1};
let arr = [2];
let test = [ [1], [1], {a:2}, {a:2}, obj, obj, arr, arr ];
Array.prototype.unique = function(){
...
}
console.log(test.unique());
通常我们利用Set和Array互转实现去重,但是该方式在判断引用类型时,并没那么给力,只有相同的引用才会被判定为相等。
console.log([...new Set(test)]);
// [[1],[1],{a:2},{a:2}, {a:1}, [2]];
如果采用对象的方式,对付普通的数据还好,碰上这种情况也是无能为力
Array.prototype.unique = function() {
var res = [];
var json = {};
for(var i = 0; i < this.length; i++){
if(!json[this[i]]){
res.push(this[i]);
json[this[i]] = true;
}
}
return res;
}
console.log(test.unique());
// [[1],{a:2},[2]] 非常神奇的是{a:1}竟然不见了
当然,如果采用极端点的方式只对引用类型的值先JSON.string()
,再来做对比,好像可以,准确的说对简单且狭义的对象类型有效,因为File、Stack、HTMLElement、class、function
等Object类型的等值判断没有json数据或字符串那般简单。
看了lodash的源码迷迷糊糊的,还是用自己的方式来实现一把。部分人可能对题意所说的通用有着不一样的理解,所以觉得束手束脚有点难。此处的场景是确定,我的思路及实现如下,有人能提出点优化建议更好。
测试结果如下