0

Date オブジェクトの形式で時間範囲のコレクションがあります。これらの時間範囲を新しい時間範囲と比較して、既存の時間範囲と重複または重複する時間範囲を追加しないようにする必要があります。

コレクションの一例です。

var timeSlots = [
    {
        BeginTime: new Date("10/25/2015 8:00 AM"),
        EndTime: new Date("10/25/2015 8:45 AM")
    },
    {
        BeginTime: new Date("10/25/2015 9:00 AM"),
        EndTime: new Date("10/25/2015 9:45 AM")
    },
    {
        BeginTime: new Date("10/25/2015 9:50 AM"),
        EndTime: new Date("10/25/2015 10:30 AM")
    }
];

前の例では、日付の日付部分は重要ではありません。時代はそうです。

午前 9 時 30 分に始まる新しい時間範囲オブジェクトがある場合、それを検出できる必要があります。

これは AngularJS アプリ内にあり、MomentJS と Angular Moment の両方にアクセスできます。

新しいタイム スロット オブジェクトを取得して、既存の他のオブジェクトと競合しないようにするにはどうすればよいですか?

// building off of the previous example
var newTimeSlot = newDate("10/25/2015 9:00 AM");
if (!conflictingTime(newTimeSlot)) {
    // then run my code
}

function conflictingTime(time) {
    // how do I do this?
}
4

3 に答える 3

0

これはオープン ソース プロジェクトのためのものであるため、ここの誰かが SO ポイントを気に入って、私が行ったよりも「ベスト プラクティス」またはより洗練されたソリューションを考え出すことを望んでいました。コメントの誰もがSOポイントを嫌っていると思います。

だからここに私の解決策があります。

angular.forEach($scope.timeSlots, function (timeSlot, index) {
    var beginTimeHasIssue = ($scope.timeSlot.BeginTime >= timeSlot.BeginTime && $scope.timeSlot.BeginTime <= timeSlot.EndTime);
    var endTimeHasIssue = ($scope.timeSlot.EndTime >= timeSlot.BeginTime && $scope.timeSlot.EndTime <= timeSlot.EndTime);

    if (beginTimeHasIssue || endTimeHasIssue) {
        hasError = true;
        $scope.HasTimeSlotError = true;
        return;
    } 
});
于 2015-10-25T23:10:33.623 に答える
0

あなたがやっている方法は提案されているとおりですが、堅牢ではないようです。たとえば、現在のスロットがない場合、forEachはあまり機能しません。また、スロットが見つかったら停止するのではなく、最後まで実行します。次の点を考慮してください。

var timeSlots = [
  {BeginTime: new Date("10/25/2015 8:00 AM"),
   EndTime: new Date("10/25/2015 8:45 AM")},
  {BeginTime: new Date("10/25/2015 9:00 AM"),
   EndTime: new Date("10/25/2015 9:45 AM")},
  {BeginTime: new Date("10/25/2015 9:50 AM"),
   EndTime: new Date("10/25/2015 10:30 AM")}
];

/*  @param   {Object} slot - object with BeginTime and EndTime date objects
 **  @returns {Boolean} true if slot fits, otherwise false
 */
function slotFits(slot) {
  if (timeSlots.length == 0) return true; // If no slots, must fit
  return timeSlots.some(function(s, i) {
    return (i == 0 && slot.EndTime <= s.BeginTime) || // slot is before all others
      (s.EndTime <= slot.BeginTime && !timeSlots[i + 1]) || // slot is after all others
      (s.EndTime <= slot.BeginTime && timeSlots[i + 1].BeginTime >= slot.EndTime) // Slot between others
  });
}

[{BeginTime: new Date("10/25/2015 7:00 AM"),  // before all, true
  EndTime: new Date("10/25/2015 8:00 AM")},
 {BeginTime: new Date("10/25/2015 10:30 AM"),  // after all, true
  EndTime: new Date("10/25/2015 11:00 AM")},
 {BeginTime: new Date("10/25/2015 8:45 AM"),  // between 0 and 1, true
  EndTime: new Date("10/25/2015 9:00 AM")},
 {BeginTime: new Date("10/25/2015 8:45 AM"),  // Overlap 1, false
  EndTime: new Date("10/25/2015 9:15 AM")}
].forEach(function(slot, i) {
  console.log('Slot ' + i + ': ' + slotFits(slot));
});

これは、スロットを見つける可能性がすべてなくなったら停止するように最適化することもできます。これには、さらに 2 行のコードが必要です。これをAngularコードに適応させることができるはずです。

PS。通常、文字列を使用してこの方法で日付を作成することはありません (つまり、非標準文字列用の組み込みパーサーを使用します) が、この例では十分です。日付は実際には次のようなものを使用して作成する必要があります:

var date = moment('10/25/2015 9:15 AM', 'MM/DD/YYYY h:mm Z').toDate();

console.log(date.toString());
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.22.2/moment.min.js"></script>

于 2015-10-26T01:43:01.893 に答える