题目描述
为 Array 对象添加一个去除重复项的方法
示例:
输入:[false, true, undefined, null, NaN, 0, 1, {}, {}, 'a', 'a', NaN]
输出:[false, true, undefined, null, NaN, 0, 1, {}, {}, 'a']
题解
- 利用Set中
Set
对象允许存储任何类型的唯一值的属性(无论是原始值或者是对象引用)。NaN
和undefined
都可以被存储在 Set 中,NaN
之间被视为相同的值(NaN 被认为是相同的,尽管 NaN !== NaN)。再用Array.from()创建数组。Array.from()
可以通过以下方式来创建数组对象:伪数组对象(拥有一个
length
属性和若干索引属性的任意对象)可迭代对象(可以获取对象中的元素,如 Map 和 Set 等)
Array.prototype.uniq = function () {
return Array.from(new Set(this))
}
- 遍历数组,将元素添加到新数组中,添加时判断是否已经添加过。注意:①NaN不等于任何,包括他自身;②var objA = {}; var objB = {}; console.log(objA == objB); 同样不相等,但是题目并不要求去除;③ arr[i]={}; arr.indexOf(arr[i]) ==i。
1. 遍历时看一下当前元素在自身元素是否能查找到,由于NaN不等于自身所以无法查找到,所以当arr.indexOf(arr[i]) = -1 时说明遇到了NaN。由于NaN若重复需要去重,因此加入flag值判断NaN是否被添加过。
Array.prototype.uniq = function () {
var args = this;
var len = args.length;
var result = [];
var flag = true;
for (var i = 0; i < len; i++) {
if (args.indexOf(args[i]) != -1) { //NaN不等于任何,包括他自身,所以args.indexOf(args[i])遇到NaN永远返回-1
if (i === args.indexOf(args[i])) {
result.push(args[i]);
}
} else if (flag) {
result.push(args[i]);
flag = false;
}
}
return result
}
2. 利用JavaScript内置方法判断元素a是否为NaN。判断NaN的方法有两种:
isNaN(a):
isNaN()
的参数如果不是 Number 类型,则会先把参数进行一次 Number 转换,所以如果直接使用,当传入字符串时,也会返回 true,即isNaN('str'); // true
。Object.is(a, NaN): 可以仅识别NaN
Array.prototype.uniq = function () {
var arr = this;
var result = [];
var len = arr.length;
var flag = true
for (var i = 0; i < len; i++) {
var type = typeof arr[i]
if (flag && Object.is(arr[i], NaN)) {
result.push(arr[i]);
flag = false;
} else if (result.indexOf(arr[i]) == -1 && !Object.is(arr[i], NaN)) {
result.push(arr[i]);
}
}
return result;
}