简体   繁体   English

从两个时间范围数组(含矩范围)计算联合时间范围

[英]Compute the union time ranges from two arrays of time ranges (with moment-range)

I have two arrays of moment-ranges , that represent periods when two individuals are busy. 我有两个矩距范围数组,表示两个人正忙的时段。

What's the best way to compute an array which contains the union time ranges that they are busy? 计算包含忙碌的并集时间范围的数组的最佳方法是什么? If two busy periods overlap for the individuals, I need the time range that represents the whole period over which they are busy. 如果两个人的繁忙时间重叠,那么我需要一个代表他们整个繁忙时间的时间范围。

Here's an example: 这是一个例子:

const firstBusyPeriods = [ 
  { start: "2017-04-05T10:00:00Z", end: "2017-04-05T12:00:00Z" },
  { start: "2017-04-05T14:00:00Z", end: "2017-04-05T15:00:00Z" }
]

const secondBusyPeriods = [
  { start: "2017-04-05T08:00:00Z", end: "2017-04-05T11:00:00Z" },
  { start: "2017-04-05T16:00:00Z", end: "2017-04-05T17:00:00Z" }
]

The resulting array should look like this: 结果数组应如下所示:

const result = [
  { start: "2017-04-05T08:00:00Z", end: "2017-04-05T12:00:00Z" },
  { start: "2017-04-05T14:00:00Z", end: "2017-04-05T15:00:00Z" },
  { start: "2017-04-05T16:00:00Z", end: "2017-04-05T17:00:00Z" }
]

The result contains a union of the overlapping busy period, and then includes the two periods that don't overlap between the individuals. 结果包含重叠的繁忙时段的并集,然后包括两个个体之间不重叠的时段。

Would it be best to concatenate the two arrays, sort the resulting array, and apply a reduce function? 最好将两个数组连接起来,对结果数组进行排序,然后应用reduce函数?

Or would it be best to recursively iterate through one of the two arrays and produce a stack with the union and non-intersecting periods as the result? 还是最好递归地遍历两个数组之一,并产生一个包含联合和非相交期间的堆栈?

I think I would go with concat and reduce : 我想我会选择concatreduce

 const firstBusyPeriods = [{ start: "2017-04-05T10:00:00Z", end: "2017-04-05T12:00:00Z" }, { start: "2017-04-05T14:00:00Z", end: "2017-04-05T15:00:00Z" } ]; const secondBusyPeriods = [{ start: "2017-04-05T08:00:00Z", end: "2017-04-05T11:00:00Z" }, { start: "2017-04-05T16:00:00Z", end: "2017-04-05T17:00:00Z" } ]; const isBetween = function(range, date) { return range.start < date && range.end > date; }; const rangesOverlap = function(rangeOne, rangeTwo) { return isBetween(rangeOne, rangeTwo.start) || isBetween(rangeOne, rangeTwo.end); }; const mergeRanges = function(rangeOne, rangeTwo) { let newRange = {} if (isBetween(rangeOne, rangeTwo.start)) { newRange.start = rangeOne.start; } else { newRange.start = rangeTwo.start; } if (isBetween(rangeOne, rangeTwo.end)) { newRange.end = rangeOne.end; } else { newRange.end = rangeTwo.end; } return newRange; }; const merge = function(rangeCollectionOne, rangeCollectionTwo) { let concatenatedCollections = rangeCollectionOne.concat(rangeCollectionTwo).sort((a,b) => a.start - b.start); let newCollection = concatenatedCollections.reduce((newCollection, range) => { let index = newCollection.findIndex(rangeToCheck => rangesOverlap(rangeToCheck, range)); if (index !== -1) { newCollection[index] = mergeRanges(newCollection[index], range); } else { newCollection.push(range); } return newCollection; }, []); return newCollection; } console.log(merge(firstBusyPeriods, secondBusyPeriods)); 

First I tried with a standard loop approach, I think recursion here is not even required to accomplish the task. 首先,我尝试使用标准循环方法,我认为甚至不需要递归即可完成任务。 IMHO reduce and concat way is more elegant. 恕我直言, reduceconcat方式更优雅。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM