时间取并交集的小工具(Go)
我们常会遇到比如司机在线时长统计的这种类型计算,
如
求并集[1,2],[4,5],[5,9],结果是[1,2],[4,9]
求所有的交集为[]
但是求相交部分为[1,2],[5,5],
三个类型,对应下面三个小函数
type TimeInterval struct { Start int End int } type TimeSlice []TimeInterval // 求全局的并集 func (ts TimeSlice) Union()TimeSlice{ if len(ts) <= 1{ return ts } sort.SliceStable(ts, func(i, j int) bool { return ts[i].Start <= ts[j].Start }) res := TimeSlice{ts[0]} for key, val := range ts{ if key == 0{ continue } if val.Start >= res[len(res)-1].Start && val.Start < res[len(res)-1].End{ if val.End > res[len(res)-1].End{ res[len(res)-1].End = val.End } }else{ res = append(res, val) } } return res } // 求全局的交集 func (ts TimeSlice)Intersect()TimeSlice{ if len(ts) <= 1{ return ts } sort.SliceStable(ts, func(i, j int) bool { return ts[i].Start < ts[j].Start }) res := TimeSlice{ts[0]} for key, val := range ts{ if key == 0{ continue } if val.Start >= res[0].Start && val.Start <= res[0].End{ res[0].Start = val.Start if val.Start < res[0].End{ res[0].End = val.End } }else { return res[:0] } } return res } // 求部分的交集 func (ts TimeSlice)IntersectSome()TimeSlice{ if len(ts) <= 1{ return ts } sort.SliceStable(ts, func(i, j int) bool { return ts[i].Start < ts[j].Start }) res := TimeSlice{ts[0]} for key, val := range ts{ if key == 0{ continue } if val.Start >= res[len(res)-1].Start && val.Start <= res[len(res)-1].End{ res[len(res)-1].Start = val.Start if val.Start < res[len(res)-1].End{ res[len(res)-1].End = val.End } }else { res = append(res, val) } } return res } func RunMergeInterval(){ case1:= TimeSlice{TimeInterval{1,2}, TimeInterval{2,5}, TimeInterval{1,9},TimeInterval{10,100},TimeInterval{11,200}} case2:= TimeSlice{TimeInterval{1,2}, TimeInterval{2,5}, TimeInterval{1,9},TimeInterval{1,100},TimeInterval{1,200}} case3:= TimeSlice{TimeInterval{1,2}, TimeInterval{2,5}, TimeInterval{1,9},TimeInterval{1,100},TimeInterval{1,200}} // res = [[1 100] [101 102]] re := case1.Union() fmt.Println(re) fmt.Println(case1.Intersect(), case2.Intersect(), case1.IntersectSome(), case3.IntersectSome()) //[{1 9} {10 200}] //[] [{2 5}] [{2 2} {11 200}] [{2 5}] }