js数组对象的处理

const arr = [{
    t1: '00:00',
    t2: '01:00'
},{
    t1: '02:00',
    t2: '04:00'
},{
    t1: '03:00',
    t2: '05:00'
}]

问题就是怎么判断这个数组对象中有时间相同或者时间有重叠交汇
比如02:00-04:00就跟03:00-05:00有重叠

我的思路是把字符串时间转为秒

const arr = [{
    t1: '00:00',
    t2: '01:00',
    f1: 0,
    f2: 3600
},{
    t1: '02:00',
    t2: '04:00',
    f1: 7200,
    f2: 14400
},{
    t1: '03:00',
    t2: '05:00',
    f1: 10800,
    f2: 18000
}]

然后对比
1.第二个对象里的f1不等于第一个对象的f1并且大于第一个对象里的f2
2.第二个对象的f2要大于当前对象的f1(保证结束时间大于开始时间)
3.根据条件返回true或者false

然后按照这个逻辑2跟1比,3跟2比,4跟3比 等等,这样对比

不知道思路对不,如果对或者不对
请教下应该怎么写?

阅读 2.6k
4 个回答
arr.sort((a,b) => a.f1 - b.f1); // 按开始时间先排个序
// 第一个条件,每个时间段的结束要大于开始
let check1 = arr.every(i => i.f2 > i.f1) 
let check2 = true;
// 第二个条件,后面的开始要大于等于前面的结束
arr.reduce((prev, next) => {check2 = check2 && next.f1 >= prev.f2; return next;});
return check1 && check2;

其实没必要转换成秒数, 字符串比较就已经足够用了

function check (arr) {
    return arr.filter((item, i) => {
        for (let j = i; j < arr.length; j++) {
            if (i === j) continue
                    
            const another = arr[j]
            if ((item.t1 >= another.t1 && item.t1 < another.t2) || (item.t2 > another.t1 && item.t1 <= another.t2) ) {
                console.log(i, item, another) // 这里输出了哪个比较没通过
                return true
            }
        }
        return false
    }).length > 0
}

console.log(check([{t1: '00:00', t2: '01:00'}, {t1: '02:00', t2: '06:00'}, {t1: '03:00', t2: '05:00'}])) // true
console.log(check([{t1: '00:00', t2: '01:00'}, {t1: '02:00', t2: '04:00'}, {t1: '03:00', t2: '05:00'}])) // true
console.log(check([{t1: '00:00', t2: '01:00'}, {t1: '03:15', t2: '04:00'}, {t1: '03:00', t2: '05:00'}])) // true
console.log(check([{t1: '00:00', t2: '01:00'}, {t1: '02:00', t2: '03:00'}, {t1: '03:00', t2: '05:00'}])) // false

判断条件可能不完整, 你自己补充吧

转换成时间戳的思路很好,以下是我的写法:

/**
* 将时间转换成时间戳,仅小时与分钟的转换,如7:03,21:00之类的时间
* @param {*} value 
*/
let filterTime = function (value) {
    const hour = Number(value.slice(0, value.indexOf(':')).replace(/^0/, '')) * 60 * 60 * 1000;
    const minute = Number(value.slice(value.indexOf(':') + 1, value.length).replace(/^0/, '')) * 60 * 1000;
    return hour + minute;
}
/**
* 判断时间段是否交叉
*/
let judgeDate = function (timeArr,startTime,endTime) {
    for (let i = 0, len = timeArr.length; i < len; i++) {
        let start = timeArr[i], end = timeArr[i];
        //满足可以修改的时间段只有两种情况,即开始时间和结束时间都小于等于已知时间段与开始时间大于已知时间段的结束时间,但结束时间需要小于等于
        //已知时间段的开始时间
        if (filterTime(startTime) <= filterTime(start) && filterTime(endTime) <= filterTime(start)) {
            return true;
        } else if (filterTime(startTime) >= filterTime(end)) {
            return true;
        }
    }
    return false;
}
if(!judgeDate()){
    console.log('时间交叉')
}

对于每一个时段,判断开始时间是否在其它所有时段内,在则有重叠;遍历完所有时段,都没有重叠就是没有。

2层循环。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题