Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Intersection of N sets [closed]

Tags:

javascript

Mozilla has an example showing how to intersect two sets like so:

var intersection = new Set([...set1].filter(x => set2.has(x)));

but what's the most concise (compact) way to intersect N sets? Thanks.

like image 955
apostl3pol Avatar asked Jan 01 '23 05:01

apostl3pol


2 Answers

You could take this approach and reduce an array of sets.

var set1 = new Set([1, 3, 4, 5, 6, 8]),
    set2 = new Set([1, 4, 5, 7, 9]),
    set3 = new Set([1, 4, 5, 8, 9]),
    intersection = [set1, set2, set3].reduce((a, b) => new Set([...a].filter(x => b.has(x))));

console.log([...intersection]);

Same with using a prototype and thisArg for filtering.

var set1 = new Set([1, 3, 4, 5, 6, 8]),
    set2 = new Set([1, 4, 5, 7, 9]),
    set3 = new Set([1, 4, 5, 8, 9]),
    intersection = [set1, set2, set3].reduce((a, b) => 
        new Set([...a].filter(Set.prototype.has, b)));

console.log([...intersection]);
like image 98
Nina Scholz Avatar answered Jan 03 '23 17:01

Nina Scholz


Found in an old answer of mine, I recommend this:

function intersect(...sets) {
    if (!sets.length) return new Set();
    const i = sets.reduce((m, s, i) => s.size < sets[m].size ? i : m, 0);
    const [smallest] = sets.splice(i, 1);
    const res = new Set();
    for (let val of smallest)
        if (sets.every(s => s.has(val)))
             res.add(val);
    return res;
}

It's both elegant and efficient :-) Its time complexity is linear to the size of the smallest input set and linear to the number of sets, and it doesn't construct any unnecessary temporary arrays on the way.

like image 21
Bergi Avatar answered Jan 03 '23 19:01

Bergi