given this input:
const set1 = new Set([10, "someText", {a: 1, b: 2}]);
const set2 = new Set([10, "someText", {a: 1, b: 2}]);
const set3 = new Set([5, "someText", {a: 3, b: 4}]);
const arr = [set1, set2, set3];
combineDupSets(arr);
Wanted result:
[
Set { 10, 'someText', { a: 1, b: 2 } },
Set { 5, 'someText', { a: 3, b: 4 } }
]
I am writing a function to eliminate all the duplicate sets, and since Set() won't check for duplicates when it's an object or set itself, I wrote the following:
function combineDupSets(arr) {
const hold = [];
arr.forEach(set =>{
const copySet = [...set];
const stringify = JSON.stringify(copySet);
if(hold.indexOf(stringify) === -1) {
hold.push(stringify)
}
})
const end = hold.map(item => JSON.parse(item));
const res = end.map(item => item = new Set(item))
return res;
}
Here, I have to use 3 arrays sized O(n) to check for this, and I was just wondering if there's any other solution that is readable that will be more efficient in checking for this for both time and space complexity?
Thank you
Instead of using indexOf
in an array, consider putting the sets onto an object or Map, where the key is the stringified set and the value is the original set. Assuming that the values are in order:
function combineDupSets(arr) {
const uniques = new Map();
for (const set of arr) {
uniques.set(JSON.stringify([...set]), set);
}
return [...uniques.values()];
}
This
arr
(O(n)
)O(n * m)
- there's no getting around that)O(n)
)If the set values aren't necessarily in order - eg, if you have
Set([true, 'foo'])
Set(['foo', true])
that should be considered equal, then it'll get a lot more complicated, since every item in each Set not only has to be iterated over, but also compared against every other item in every other Set somehow. One way to implement this is to sort by the stringified values:
function combineDupSets(arr) {
const uniques = new Map();
for (const set of arr) {
const key = [...set].map(JSON.stringify).sort().join();
uniques.set(key, set);
}
return [...uniques.values()];
}