题目描述
为 Array 对象添加一个去除重复项的方法
示例1
输入: [false, true, undefined, null, NaN, 0, 1, {}, {}, ‘a’, ‘a’, NaN]
输出: [false, true, undefined, null, NaN, 0, 1, {}, {}, ‘a’]
这个题,我首先考虑到的是参考纯数字去重的算法——快慢指针进行求解:
Array.prototype.uniq = function () {
let newarr = [];
for(var i = 0; i < this.length; i++){
for(var j = i + 1; j < this.length; j++){
if(this[i] === this[j]){
this.splice(i,0);
}
}
}
return newarr;
}
其次想的是使用 indexOf 的方法求解,代码如下:
Array.prototype.uniq = function () {
let newarr = [];
for(var i = 0; i < this.length; i++){
if(newarr.indexOf(this[i]) < 0){
newarr.push(this[i]);
}
}
return newarr;
}
这一个解答也出现问题,我一时之间没有想到解答,看了一下题解,发现了一个类似的解答过程,代码如下:
Array.prototype.uniq = function () {
let newarr = [];
for(var i = 0; i < this.length; i++){
if(!newarr.includes(this[i])){
newarr.push(this[i]);
}
}
return newarr;
}
这里的解答过程,就是使用 ES6 的数组新方法 includes,详细查看菜鸟教程的解答。
includes 与 indexOf 的区别:
在ES5,Array已经提供了indexOf用来查找某个元素的位置,如果不存在就返回-1,但是这个函数在判断数组是否包含某个元素时有两个小不足,第一个是它会返回-1和元素的位置来表示是否包含,在定位方面是没问题,就是不够语义化。另一个问题是不能判断是否有NaN的元素。 ES6提供了Array.includes()函数判断是否包含某一元素,除了不能定位外,解决了indexOf的上述的两个问题。它直接返回true或者false表示是否包含元素,对NaN一样能有效。
利用 set 对象求解
Set 对象 Set 对象允许你存储任何类型的唯一值,无论是原始值或者是对象引用。
Set 中的特殊值 Set 对象存储的值总是唯一的,所以需要判断两个值是否恒等。有几个特殊值需要特殊对待:
- +0 与 -0 在存储判断唯一性的时候是恒等的,所以不重复;
- undefined 与 undefined 是恒等的,所以不重复;
- NaN 与 NaN 是不恒等的,但是在 Set 中只能存一个,不重复。
Array.prototype.uniq = function () {
return Array.from(new Set(this))
}
关于第一种解法,我在思考思考问题在哪。 若有不足之处,欢迎大家批评指正。关于第一种解法的问题也欢迎大家指点。
|