如何在JavaScript中拼接范围?

时间:2014-04-16 20:14:43

标签: javascript

我正在制定一个计划管理系统,该系统将一个人的工作计划加载到一个数组中,然后允许用户注入"那一天内的新转变。当然,代码必须遵循一些规则,它们是:

  1. 现有班次与添加项目之间必须没有差距。这意味着添加项目的结束时间必须等于或大于第一项目的开始时间,并且添加项目的开始时间必须等于或小于最后一项“#39”结束时间。

  2. 添加的班次必须覆盖在其时间范围内发生的任何现有班次。本质上,它需要将自己拼接到数组中,但我不确定如何使用.splice()方法这样做。

  3. 必须截断/压缩任何受影响的时间块以容纳新项目。例如,如果存在持续时间为一小时的现有时间块,并且我们在开始的20分钟内注入10分钟的块,则将导致原始块的前20分钟部分,接着是10分钟。添加项目,然后是原始块的其余部分。添加的项目也必须能够与其他时间块重叠。因此,如果我们添加一个包含4个其他时间块(或者在其中开始/停止!)的3小时块,它必须覆盖每个块。

  4. 这似乎是一项非常简单的任务,因为它基本上只是拼接范围,但我不知道如何在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中拼接范围?

1 个答案:

答案 0 :(得分:0)

您可以分别根据开始结束来考虑您的时间段。我从概念上将其视为链表,您可以将其实现为数组。特别要求列表中的每个节点必须遵循START_TIME -> END_TIME的顺序,并且永远不要有2个START_TIME或2个END_TIME个节点彼此相邻。中间(空闲时间块)中的任何一个也由START_TIMEEND_TIME节点定义。

SSTART_TIME

EEND_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)