获取匹配区间

Get matching interval

所以我从 两个简单的事情开始:


let intervals = {
    "08:00 - 09:00" : "Morning yoga",
    "09:00 - 10:00" : "Breakfast",
    "10:00 - 13:00" : "School Period",
    "13:00 - 14:00" : "Basketball",
    "14:00 - 16:00" : "Free Period",
    "16:00 - 17:00" : "Evening Meal",
    "17:00 - 18:00" : "Exercise Period",
    "18:00 - 19:00" : "Shower Block",
    "19:00 - 22:00" : "Evening Free Time",
    "22:00 - 23:00" : "Evening Rollcall",
    "23:00 - 08:00" : "Lights Out"
  }

我想将 间隔的名称 提取到给定的 currentTime 以便我从中获得例如:


到目前为止我得到的是下面的代码,但显然里面有一些错误。

let getSchedule = function(time) {
  let scheduleIndex = 0;
  let current = getMinute(time);
  let intervalArray = []

  for (let key in schedule)
    intervalArray.push([getMinute(key.split(" - ")[0]),
      getMinute(key.split(" - ")[1])
    ]);

  for (let index = 0; index < intervalArray.length; index++) {
    let interval = intervalArray[index]
    if (current >= interval[0] && current < interval[1]) {
      scheduleIndex = index;
      break;
    }
  };
  return schedule[Object.keys(schedule)[scheduleIndex]]
}

let getMinute = function(time) {
  let hour = parseInt(time.split(":")[0]),
    minute = parseInt(time.split(":")[1]);
  return minute + hour * 60;
}

let result = getSchedule("16:22")
console.log(result)

result = getSchedule("02:00")
console.log(result)
<script>
  let schedule = {
    "08:00 - 09:00": "Morning yoga",
    "09:00 - 10:00": "Breakfast",
    "10:00 - 13:00": "School Period",
    "13:00 - 14:00": "Basketball",
    "14:00 - 16:00": "Free Period",
    "16:00 - 17:00": "Evening Meal",
    "17:00 - 18:00": "Exercise Period",
    "18:00 - 19:00": "Shower Block",
    "19:00 - 22:00": "Evening Free Time",
    "22:00 - 23:00": "Evening Rollcall",
    "23:00 - 08:00": "Lights Out"
  }
</script>

编辑:请注意,整点时间会更改状态,因此 23:00 的状态为 Lights Out22:59 具有状态 Evening Rollcall.

另请注意,我无法更改 intervals 对象。它的结构必须保留。

脚本最初将 scheduleIndex 设置为 0(默认值)并且从不检查是否找到匹配的区间

您的逻辑永远不会匹配 "Lights Out" 区间,因为结束值小于起始值,而您的逻辑不允许这样。

getSchedule 因此 return 是 schedule 中的 "default" 元素,"Morning Yoga" 而不是 "Lights Out".

可能的解决方案:

  1. 更改您的逻辑以正确匹配 "Lights Out" 间隔。
  2. 将您的 "Lights Out" 间隔分成两部分,“00:00 - 08:00”和“23:00 - 23:59”并保持当前逻辑
  3. 保持你的逻辑并添加错误检查(将 scheduleIndex 设置为无效值并在你 return 结果之前对其进行测试)并从计划中删除 "Lights Out" 间隔并假设任何不匹配的都是这个默认间隔。 (如下图)

let getSchedule = function(time) {
  let scheduleIndex = -1;
  let current = getMinute(time);
  let intervalArray = []

  for (let key in schedule)
    intervalArray.push([getMinute(key.split(" - ")[0]),
      getMinute(key.split(" - ")[1])
    ]);

  for (let index = 0; index < intervalArray.length; index++) {
    let interval = intervalArray[index]
    if (current >= interval[0] && current < interval[1]) {
      scheduleIndex = index;
      break;
    }
  };
  return -1 == scheduleIndex? "Lights Out" : schedule[Object.keys(schedule)[scheduleIndex]];
}

let getMinute = function(time) {
  let hour = parseInt(time.split(":")[0]),
    minute = parseInt(time.split(":")[1]);
  return minute + hour * 60;
}

let result = getSchedule("16:22")
console.log(result)

result = getSchedule("02:00")
console.log(result)
<script>
  let schedule = {
    "08:00 - 09:00": "Morning yoga",
    "09:00 - 10:00": "Breakfast",
    "10:00 - 13:00": "School Period",
    "13:00 - 14:00": "Basketball",
    "14:00 - 16:00": "Free Period",
    "16:00 - 17:00": "Evening Meal",
    "17:00 - 18:00": "Exercise Period",
    "18:00 - 19:00": "Shower Block",
    "19:00 - 22:00": "Evening Free Time",
    "22:00 - 23:00": "Evening Rollcall",
  }
</script>

如果你改变数据结构,它会变得更简单。

const schedule = {
  "Morning yoga": [800, 900],
  "Breakfast": [900, 1000]
};

const getSchedule = timeString => {
  const time = +timeString.replace(":", "");
  const result = [];
  for (const key in schedule) {
    if (time >= schedule[key][0] && time <= schedule[key][1]) {
      result.push(key);
    }
  }
  return result;
};

const result = getSchedule("09:22");
console.log(result);

我做的有点不同。可能对你有帮助。

let schedule = {
  "08:00 - 09:00": "Morning yoga",
  "09:00 - 10:00": "Breakfast",
  "10:00 - 13:00": "School Period",
  "13:00 - 14:00": "Basketball",
  "14:00 - 16:00": "Free Period",
  "16:00 - 17:00": "Evening Meal",
  "17:00 - 18:00": "Exercise Period",
  "18:00 - 19:00": "Shower Block",
  "19:00 - 22:00": "Evening Free Time",
  "22:00 - 23:00": "Evening Rollcall",
  "23:00 - 08:00": "Lights Out"
}
var getSchedule = function(time) {
let fullDaySchedule = {}
  Object.entries(schedule).forEach(([currentTime, work]) => {
    let startTime = +currentTime.split(" - ")[0].split(":")[0],
      endTime = +currentTime.split(" - ")[1].split(":")[0];

    (startTime > endTime) && (endTime = (23 - startTime) + (23 + endTime))

    for (let index = startTime; index <= endTime; index++) {
      fullDaySchedule[(index % 24)] = work;
    }
  })

  console.log(fullDaySchedule[+time.split(":")[0]])
}

// You can test this
getSchedule("02:00")

我重新修改了您的代码 a bit。它以更实用的方式完成,我相信可读的方式。我还考虑了一些边缘情况(当然不是全部,因为我相信情况并非如此)。看看这个坏男孩:

// Keep in mind that for e.g. `14:00` you have two parameters that fullfil the requirement: 
// `Basketball` and `Free Period`. 
// This constrain should be specified in the code somewhere.
// Otherwise the first value will be taken.
let schedule = {
    "08:00 - 09:00" : "Morning yoga",
    "09:00 - 10:00" : "Breakfast",
    "10:00 - 13:00" : "School Period",
    "13:00 - 14:00" : "Basketball",
    "14:00 - 16:00" : "Free Period",
    "16:00 - 17:00" : "Evening Meal",
    "17:00 - 18:00" : "Exercise Period",
    "18:00 - 19:00" : "Shower Block",
    "19:00 - 22:00" : "Evening Free Time",
    "22:00 - 23:00" : "Evening Rollcall",
    "23:00 - 08:00" : "Lights Out"
  }


let newSchedule = Object
  .entries(schedule)
  .reduce((acc, entry) => {
    const newInterval = {
      from: Number(entry[0].slice(0,5).replace(':','')),
      to: Number(entry[0].slice(-5).replace(':','')),
      value: entry[1],
    };
    return [...acc, newInterval];
  }, [])
  .reduce((acc, { from, to, value}) => {
    // this step is only needed when you can't set ranges in `schedule` object manually
    let intervals = [{ from, to, value }];
    if(from > to) {
      intervals = [
        { 
          from, 
          to: 2400,
          value,
        },
        { 
          from: 0, 
          to,
          value,
        },
      ];
    }
    return [...acc, ...intervals];
  }, []);

const getSchedule = (time) => {
  const timeAsNumber = Number(time.replace(':', ''));
  return newSchedule.find(interval => {
    return timeAsNumber >= interval.from && timeAsNumber <= interval.to;
  }).value
}

console.log(getSchedule('02:00'))
console.log(getSchedule('18:00'))

我鼓励你进一步重构它,例如进入更实用的方法,更高性能,或者只是更清洁。