区间合并

最近搞个新项目,涉及到区间合并的问题。

需求分析

最近公司开启新项目,其中有一个这样的需求:会员可以根据医生的排班表进行预约,当预约完成之后,会以矩形的形式占据预约的时间段落,大概是下面这样:
占位
如果是已经预约的,其他会员可以长按或者进行其他操作,进行再次预约,即同一时间段可以被多人预约。例如,如果 A 预约了医生 08:00 – 10:00,B 预约了医生 09:00 – 10:00,那么,这两段数据就会重合。
刚开始开发的时候并没有这个需求,经过讨论,我们决定进行区间合并,将预约相同时间段内的数据统一绘制在一个矩形框内。

思路分析

需求清晰之后,就是如何将时间段进行合并的问题了。
首先服务器返回近期的数据,然后我们按照天数,分组,一天数据绘制一列。
然后,进行区间合并。将一天的数据安装预约开始时间从早到晚排序产生数组A。使用区间表示,比如 08:00 – 10:00 表示为 [8,10],以数组 A 第一个元素初始化一个区间 a[start,end], 开始时间记作a.start,结束时间记作a.end,接下来遍历 A,当前区间元素记作c,,会出现以下情况:

  1. c.start >= a.start && c.end <= a.end,即,当前时间在区间内,不处理;
  2. c.start >= a.start && c.end > a.end,即,开始时间在区间内,结束时间晚于当前结束时间,那么,修改 a.end = c.end;
  3. c.start > a.end,即 c 不在 a 之内,那么修改当前的开始和结束。
  4. 完成合并

示例代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
- (void)testCode {
NSArray *a = @[@8,@11];
NSArray *b = @[@2,@4];
NSArray *c = @[@0,@2];
NSArray *d = @[@15,@18];
NSArray *e = @[@7,@16];
NSArray *all = @[a, b, c, d, e];
/// 区间排序
NSArray *sortAry = [all sortedArrayUsingComparator:^NSComparisonResult(NSArray *obj1, NSArray *obj2) {
return [obj1.firstObject integerValue] > [obj2.firstObject integerValue];
}];
NSMutableArray *result = [NSMutableArray array];
NSInteger pre = 0;
NSInteger next = 0;
for (NSInteger i = 0; i < sortAry.count; i++) {
NSArray <NSNumber *> *c = sortAry[i];
NSInteger start = c.firstObject.integerValue;
NSInteger end = c.lastObject.integerValue;
if (i == 0) {
pre = start;
next = end;
[result addObject:c];
}
if (start >= pre && end <= next) {
continue;
}
if (start >= pre && end >= next) {
if (start > next) {
pre = start;
next = end;
[result addObject:c];
} else {
next = end;
NSArray *ary = mAry.lastObject;
[result removeLastObject];
[result addObject:@[ary.firstObject, @(next)]];
}
}
}
NSLog(@"%@", result);
}