N套相交

时间:2019-03-07 21:24:10

标签: javascript

Mozilla有an example展示了如何像这样相交两个集合:

DECLARE @StartDate DATETIME
DECLARE @EndDate DATETIME
SET @StartDate = '2019-03-07 00:00:00.000'
SET @EndDate = '2019-03-11 23:59:59.000'

Declare @TotalMins int
Declare @Weekends int
Declare @FinalMinutes int

Set @TotalMins =  DATEDIFF(MINUTE, @StartDate,@EndDate);

Set @Weekends = 
  (DATEDIFF(wk, @StartDate, @EndDate) * 2)
   +(CASE WHEN DATENAME(dw, @StartDate) = 'Sunday'   THEN 1 ELSE 0 END)
   +(CASE WHEN DATENAME(dw, @EndDate)   = 'Saturday' THEN 1 ELSE 0 END)

Set @FinalMinutes = @TotalMins -  (@Weekends * 24 * 60)
Select @FinalMinutes

但是与N个集合相交的最简洁(紧凑)方式是什么?谢谢。

3 个答案:

答案 0 :(得分:5)

您可以采用这种方法并减少一组数组。

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]);

与使用原型和thisArg进行过滤相同。

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]);

答案 1 :(得分:3)

an old answer of mine中找到,我建议这样做:

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;
}

既优雅又高效:-)它的时间复杂度与最小输入集的大小成线性关系,与集合数成线性关系,并且在此过程中不会构造任何不必要的临时数组。

答案 2 :(得分:0)

这是另一种方法,获取一组数组中的第一组,然后通过属于所有其他组的那些元素对其进行过滤:

let sets = [
    new Set([1, 3, 4, 5, 6, 8]),
    new Set([1, 4, 5, 7, 9]),
    new Set([1, 4, 5, 8, 9])
];

// Generate the intersection.
let intersection = new Set([...sets[0]].filter(
    x => sets.slice(1).every(s => s.has(x))
));

console.log([...intersection]);
.as-console {background-color:black !important; color:lime;}
.as-console-wrapper {max-height:100% !important; top:0;}