function deepDedup(arr) {
const seen = new Set();
const deduplicatedArr = [];
function isPrimitive(value) {
return (
typeof value === 'string' ||
typeof value === 'number' ||
typeof value === 'boolean' ||
typeof value === 'symbol' ||
value === null ||
value === undefined
);
}
function generateKey(value) {
if (isPrimitive(value)) {
return value;
} else if (Array.isArray(value)) {
return '[' + value.map(generateKey).join(',') + ']';
} else if (typeof value === 'object') {
// Sort keys to handle different insertion orders
const sortedKeys = Object.keys(value).sort();
return '{' + sortedKeys.map(key => key + ':' + generateKey(value[key])).join(',') + '}';
}
}
function dedup(arr) {
for (const item of arr) {
if (Array.isArray(item)) {
const dedupedSubArray = [];
dedup(item); // Recursively deduplicate sub-arrays in-place
const key = generateKey(item)
if (!seen.has(key)) {
seen.add(key);
deduplicatedArr.push(item);
}
} else if (typeof item === 'object' && item !== null) {
const key = generateKey(item);
if (!seen.has(key)) {
seen.add(key);
deduplicatedArr.push(item);
for (const key in item) { // Recursively deduplicate object values
if (Array.isArray(item[key])) {
dedup(item[key]);
}
}
}
} else {
const key = generateKey(item);
if (!seen.has(key)) {
seen.add(key);
deduplicatedArr.push(item);
}
}
}
}
dedup(arr);
return deduplicatedArr;
}
// Test cases:
const arr1 = [1, 2, 2, 3, [4, 4, 5], [4, 4, 5], 6, [7, [8, 8]]];
console.log(deepDedup(arr1)); // Output: [1, 2, 3, [4, 5], 6, [7, [8]]]
const arr2 = [{ a: 1, b: 2 }, { a: 1, b: 2 }, { a: 1, b: { c: 3 } }, { a: 1, b: { c: 3 } }];
console.log(deepDedup(arr2)); // Output: [{ a: 1, b: 2 }, { a: 1, b: { c: 3 } }]
const arr3 = [[1, 2, [3, 3]], [1, 2, [3, 3]]];
console.log(deepDedup(arr3)); // Output: [[1, 2, [3]]]
const arr4 = [NaN, NaN, 1, NaN];
console.log(deepDedup(arr4)); // Output: [NaN, 1]
const arr5 = [
{ a: 1, b: [2, 2, { c: 3 }] },
{ a: 1, b: [2, 2, { c: 3 }] },
];
console.log(deepDedup(arr5)); // Output: [{ a: 1, b: [2, { c: 3 }] }]
const arr6 = [{ a: 1, b: [2, 2, { c: 3, d: [4, 4] }] }, { a: 1, b: [2, 2, { c: 3, d: [4, 4] }] }];
console.log(deepDedup(arr6)); // Output: [{a: 1, b: [2, {c: 3, d: [4]}]}]
const arr7 = [{a:1, b:2}, {b:2, a:1}]; // Different insertion order for object keys
console.log(deepDedup(arr7)); // Output: [{a: 1,