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个集合相交的最简洁(紧凑)方式是什么?谢谢。
答案 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;}