我正在制定一个计划管理系统,该系统将一个人的工作计划加载到一个数组中,然后允许用户注入"那一天内的新转变。当然,代码必须遵循一些规则,它们是:
现有班次与添加项目之间必须没有差距。这意味着添加项目的结束时间必须等于或大于第一项目的开始时间,并且添加项目的开始时间必须等于或小于最后一项“#39”结束时间。
添加的班次必须覆盖在其时间范围内发生的任何现有班次。本质上,它需要将自己拼接到数组中,但我不确定如何使用.splice()方法这样做。
必须截断/压缩任何受影响的时间块以容纳新项目。例如,如果存在持续时间为一小时的现有时间块,并且我们在开始的20分钟内注入10分钟的块,则将导致原始块的前20分钟部分,接着是10分钟。添加项目,然后是原始块的其余部分。添加的项目也必须能够与其他时间块重叠。因此,如果我们添加一个包含4个其他时间块(或者在其中开始/停止!)的3小时块,它必须覆盖每个块。
这似乎是一项非常简单的任务,因为它基本上只是拼接范围,但我不知道如何在JavaScript中拼接范围。
以下是我为实施这些规则而编写的代码:
var obj = {
start: '',
end: '',
};
var objArray = [];
var tmpArray = [];
var finalArray = [];
objArray.push({start: "12:00", end: "12:45"});
objArray.push({start: "12:45", end: "1:00"});
objArray.push({start: "1:00", end: "1:30"});
objArray.push({start: "1:30", end: "2:30"});
// added object
obj.start = "12:00";
obj.end = "12:10";
for (var i = 0; i < objArray.length; i++) { tmpArray.push(objArray[i]); }
//tmpArray = objArray; // preserve the original array
objArray.push(obj);
console.clear();
console.log("%o", objArray);
objArray.sort(function(a, b) { var x = a.start; var y = b.start; return ((x < y) ? -1 : ((x > y) ? 1 : 0)); });
// sanity check
if (obj.start >= obj.end){
console.log('Time logic is invalid.');
return false;
}
if (obj.end < tmpArray[0].start) {
console.log('There is a gap before the first item.');
return false;
}
if (obj.start > tmpArray[tmpArray.length - 1].end){
console.log('There is a gap after the last item.');
return false;
}
// Now for the fun stuff...
for (var i = 0; i < objArray.length; i++){
var tmpobj = objArray[i];
if (tmpobj.start == obj.start && tmpobj.end == obj.end){ // find our inserted object
index = i;
console.log('<<< obj injected: %s - %s [%d] >>>', obj.start, obj.end, index);
if (index == 0){ // is first item, start time was less than first item's start time
finalArray.push(obj);
if (obj.end == tmpArray[0].start){
finalArray.push(tmpArray[0]); // item insertion was a complete prepend...
} else if (obj.end >= tmpArray[tmpArray.length - 1].end){
console.log('entire array is consumed'); // item covers entire shift...
} else {
// This code is reached when obj start time is before or equal to first item
console.log('obj <= tmpArray[0].start, end > tmpArray[0].start');
}
} else {
if (obj.start == tmpArray[tmpArray.length - 1].end){
console.log('Item added at end of shift');
finalArray.push(tmpArray[i - 1]);
finalArray.push(obj);
}
}
} else {
console.log('obj tested: %s - %s [%d]', tmpobj.start, tmpobj.end, i);
if (obj.start > tmpobj.end) {
finalArray.push(tmpobj);
}
if (obj.end < tmpobj.start) {
finalArray.push(tmpobj);
}
}
// now iterate through array and combine like terms (activity type)
}
for (var i = 0; i < finalArray.length; i++){
console.log('%d) s: %s, e: %s', i, finalArray[i].start, finalArray[i].end);
}
如何在JavaScript中拼接范围?
答案 0 :(得分:0)
您可以分别根据开始和结束来考虑您的时间段。我从概念上将其视为链表,您可以将其实现为数组。特别要求列表中的每个节点必须遵循START_TIME -> END_TIME
的顺序,并且永远不要有2个START_TIME
或2个END_TIME
个节点彼此相邻。中间(空闲时间块)中的任何一个也由START_TIME
和END_TIME
节点定义。
S
是START_TIME
E
是END_TIME
有效时间块数组可能如下[S1, E1, S2, E2, S3 ,E3]
然后,当编写逻辑以插入新的时间块时,您可以通过转到相应的START_TIME
节点找到新的时间块,然后&#34; splice&#34;通过创建END_TIME E*
节点和标记新块开头的新START_TIME S-NEW
节点。
[S1, E1 ,S2 ,E* ,S-NEW, E2, S3, E3]
然后,您可以根据需要创建END_TIME
节点来定义结束时间(删除旧END_TIME E2
并创建&#34;免费&#34;块),
[S1, E1, S2, E*, S-NEW, E-NEW, S-FREE, E-FREE, S3, E3]
或重复使用您拼接的旧END_TIME E2
节点&#34;如果他们在同一时间结束
[S1, E1, S2, E*, S-NEW, E2, S3, E3]
你最终伤害大脑的原因是因为你的代码一次性做得太多了。我建议将其分解为函数,这里有一些建议:
canStart(time)
canEnd(time)
insertBlock(startBlock, endBlock)
removeBlock(startBlock, endBlock)