核心思想
把需要去重数组中的元素作为属性名查对象中有没有它对应的属性值,如果有,则该元素重复了。
去重详细步骤
- 创建一个空的
JS
对象,用于去重。创建一个空的数组,用于保存去重后的元素。 - 遍历原数组,将数组中的元素作为上一步创建的空对象的属性名,根据属性名获取属性值
- 若能根据属性名从对象中获取到属性值,则说明重复了,不执行if代码块内的代码。注意下面判断重复的逻辑,判断条件是对获取到属性值取反,所以,属性值不能设置为
0
或者false
。如果属性值设置为0
或者false
,当根据属性名从对象中获取到属性值再取反,也会通过判断条件进入到if代码块内,这样就无法去重了。 - 若如果对象中没有对应的属性,
obj[temp]
获取到的值是undefined
,对其取反是true
,说明没有重复,进入if
代码块内部执行。首先,向第一步中的对象添加一个属性,属性名必须为数组中的元素,属性值不能设置为0
或者false
,其他的任何值都可以,建议取1
或者true
,这是判断元素是否重复的重要条件。接着,把元素放进结果数组中。 - 把结果数组返回
// 非对象数组去重
function distinct(array){
var obj = {};
var result = [];
for(var i = 0;i < array.length;i++){
var temp = array[i];
//如果能查到,则说明重复了
if(!obj[temp]){
obj[temp] = 1;
result.push(temp);
}
}
return result;
}
注意!!!上述方法只能适用于元素不是对象的数组去重
首先明确:当把js
对象作为属性名向对象中添加一个属性时,js会把[object Object]
作为属性名!
如果数组中的元素是js
对象,在if
代码块内,把数组中的对象作为属性名,向 去重步骤第一步 中的对象添加属性后,会发现添加属性后的对象的属性名是[object Object]
。并且之后根据数组中对象元素作为属性名,去去重步骤第一步 中的对象查属性值的时候,都会被转换为查属性名为[object Object]
的属性值。所以在第一次进入if
代码块内添加了一个属性之后,后续的if
判断都会不成立,故去重失败!
图示
利用上述去重方法给对象数组去重,js对象中的实际情况是箭头所指的地方,具体展示如下
控制台打印结果,可以看到去重后数组中只有一个对象了,因为如上所说,把对象作为属性名向对象中添加了一个属性之后,后续的if
条件判断都不会成立,所以就不会进到if
代码块里面执行,自然就不会有添加到结果数组的操作了。