Appearance
数组去重,很多人第一时间想到的是[...new Set(arr)],但是这种方式只能对基本数据类型进行去重。
Set的内部实现中,是使用Object.is()来判断是不是重复
js
Object.is(0, -0); // false
Object.is(NaN, NaN); // true
Object.is({}, {}); // false所以对于数组去重这件事,还有一个最关键的问题:怎么定义为重复?
在通常的业务代码中,两个空对象{}应该被定义为重复数据才对,此时我们需要加上一个条件:
两个属性相同的对象也认为是重复的
上代码
js
function uniqueArray(arr) {
const result = [];
outer: for (const item of arr) {
for (const r of result) {
if (equals(item, r)) continue outer;
}
result.push(item);
}
return result;
}怎么判断两个数据是否相同?
首先我们需要判断数据是否原始值,也就是基本数据类型,如果是,那么直接用Object.is()去判断即可
js
function isPrimitive(val) {
return val !== Object(val);
}TIP
Object传入数组或者对象,会返回原本的数组或对象,传入数字或字符串,则会得到它的包装类
判断两个数据是否相同
js
function equals(value1, value2) {
if (isPrimitive(value1) || isPrimitive(value2)) {
return Object.is(value1, value2);
}
const entries1 = Object.entries(value1);
const entries2 = Object.entries(value2);
if (entries1.length !== entries2.length) return false;
for (const [key, val] of entries1) {
// 当此对象的key不存在另一个对象中的时候,直接返回false
if (!Object.hasOwnProperty(value2, key)) return false;
// 属性值有可能为对象类型,递归判断
if (!equals(val, value2[key])) return false;
}
return true;
}