数组去重,并且key和val相同的对象视为相同的,需要去重。
主函数:
/**
* 数组去重
* 两个属性相同的对象也认为是相同的
* @param {Array} arr
* @return {Array}
*/
function uniqueArray(arr) {
const result = []
// outer: 标签,标记外层循环
outer: for (const element of arr) {
for (const res of result) {
if (equal(element, res)) {
continue outer
}
}
result.push(element)
}
return result
}
辅助函数一:isPrimitive判断原始类型
function isPrimitive(val) {
return val === null || (typeof val !== "object" && typeof val !== "function")
}
辅助函数二:equal判断两个值是否相同
function equal(val1, val2) {
if (isPrimitive(val1) || isPrimitive(val2)) {
return Object.is(val1, val2)
}
const entries1 = Object.entries(val1)
const entries2 = Object.entries(val2)
const keys1 = Object.keys(val1)
const keys2 = Object.keys(val2)
if (entries1.length !== entries2.length) {
return false
}
for (const key1 of keys1) {
if (!keys2.includes(key1)) {
return false
}
}
// 双向检查才能正确判断
// const obj3 = { a: 1, b: 2 }
// const obj4 = { a: 1, b: 2, c: 3 }
for (const key2 of keys2) {
if (!keys1.includes(key2)) {
return false
}
}
for (const [key, value] of entries1) {
if (!equal(value, val2[key])) {
return false
}
}
return true
}
测试案例:
const arr = [
{ name: "John", age: 25 },
{ name: "Jane", age: 30 },
{ name: "John", age: 25 }, // 重复对象
[1, 2, 3],
[1, 2, 3], // 重复数组
"hello",
"hello", // 重复字符串
{ a: 1, b: undefined },
{ a: 1, c: undefined }
]
console.log(uniqueArray(arr))
//打印
[
{ name: 'John', age: 25 },
{ name: 'Jane', age: 30 },
[ 1, 2, 3 ],
'hello',
{ a: 1, b: undefined },
{ a: 1, c: undefined }
]