假设有一个对象数组,它们仅仅是对象的属性位置不一样
const arr = [
{a:1,b:2},
{b:2,a:1},
{a:1,b:2},
{b:2,a:1},
{a:1,b:2,c:{a:1,b:2}},
{b:2,a:1,c:{b:2,a:1}},
{a:1,b:2,c:{a:1,b:2}},
];
那么现在有两种方法对其进行去重
第一种: 只针对对象整体进行去重 不考虑对象中的值是否重复
// unique 函数用于删除数组中所有重复的对象。它使用一个叫做 stringifiedSet 的 Set 对象来存储已经出现过的字符串表示的对象。
function unique(arr) {
// stringifiedSet 用于存储已经出现过的对象的字符串表示
const stringifiedSet = new Set();
// result 是一个新的数组,它只包含原始数组中唯一的对象
const result = arr.filter(obj => {
// stringifiedObj 是当前对象 obj 的字符串表示
const stringifiedObj = JSON.stringify(obj);
// 如果 stringifiedObj 已经在 stringifiedSet 中,那么过滤器会返回 false,这个对象就不会出现在结果数组中
if (stringifiedSet.has(stringifiedObj)) {
return false;
} else {
// 否则,将 stringifiedObj 添加到 stringifiedSet 中,并返回 true,这个对象就会出现在结果数组中
stringifiedSet.add(stringifiedObj);
return true;
}
});
// 返回结果数组
return result;
}
console.log('uniqueArr', unique(arr))
/*
uniqueArr:
[
{ a: 1, b: 2 },
{ b: 2, a: 1 },
{ a: 1, b: 2, c: {… } },
{ b: 2, a: 1, c: {… } }
]
*/
第二种 对象内所有值相同也算重复
// deduplicateDeep 函数用于深度删除数组中的重复对象。它使用一个叫做 seen 的 Set 对象来存储已经出现过的对象的哈希值。
function deduplicateDeep(arr) {
// seen 用于存储已经出现过的对象的哈希值
const seen = new Set();
// result 是一个新的数组,它只包含原始数组中唯一的对象
const result = [];
// 遍历原始数组中的每个对象
for (let item of arr) {
// entries 是当前对象 item 的键值对数组
let entries = Object.entries(item);
// sortedEntries 是 entries 的拷贝,并且已经排序过的数组
let sortedEntries = [...entries].sort(); // 先复制数组,然后排序
// hash 是 sortedEntries 的字符串表示,它是由排序后的键值对数组转化而来的
let hash = sortedEntries.join(','); // 将排序后的数组转换为字符串
// 如果 hash 已经在 seen 中,那么就不会将当前对象添加到 result 中
if (!seen.has(hash)) {
seen.add(hash); // 将 hash 添加到 seen 中,以便记录已经出现过的对象
result.push(item); // 将当前对象添加到 result 中
}
}
// 返回结果数组
return result;
}
console.log(deduplicateDeep(arr)
/*
[
{ a: 1, b: 2 },
{ a: 1, b: 2, c: { a: 1, b: 2 } },
]
*/