2016-04-16 12 views
2

Angenommen, es gibt ein System, das die Verfügbarkeit von Daten für Ereignisse anzeigt. Wir haben einen Hauptdatenbereich, in dem alle Veranstaltungen stattfinden. Ereignisse können auch Datumsbereiche sein.Verfügbare Tage in einem Datumsbereich finden

Beispiel:

[Date X]========================================[Date Y] 
     [A]=====[A]  [B]=====[B][C]=====[C] 
     [ Event A ][ Open ][ Event B ][ Event C ] 

Wo Datum X und Y Datum des Hauptdatumsbereich, wo Veranstaltungen gehen. Und A, B und C sind Ereignisse, die geplant wurden.

Wie kann ich den offenen Datumsbereich effizient abrufen?

Beispiel 2:

var rangeStart = new Date("04-01-2016"); 
var rangeEnd = new Date("04-31-2016"); 

var eventAStart = new Date("04-01-2016"); 
var eventAEnd = new Date("04-06-2016"); 

var eventBStart = new Date("04-15-2016"); 
var eventBEnd = new Date("04-30-2016"); 

ich so etwas zurückgeben müssen:

var availableRangeStart = "04-07-2015"; 
var availableRangeEnd = "04-14-2016"; 

, weil diese die Daten im Hauptbereich sind, die von „Ereignisse“ nicht überlappen reicht.

Um genau zu sein auf das, was ich zu tun versucht:

Meine App ist ein Reiseplaner, wo der Benutzer die Daten für ihre Reise setzt und fügt dann verschiedene Ziele zu dieser Reise, die ihre eigenen Termine haben. (Der User geht vom 1. April bis zum 30. April nach Europa, vom 1. April bis zum 6. April in Paris, dann vom 15. April bis zum 30. April in London). Aber vom 7. April bis 14. April hat der Benutzer nichts geplant. Ich versuche, diese Daten zurückzugeben, sodass die Daten beim Hinzufügen eines neuen Ziels vorab ausgefüllt werden.

+1

ich nicht wirklich bekommen, was Sie –

+0

@YehiaAwad Leider bedeuten, sollte ich war klarer. Sagen wir mal für den Monat April sind 3 Veranstaltungen geplant. Event A ist vom 1. April bis zum 6. April, Event B ist vom 15. April bis 20. April und Event C ist vom 21. April bis zum 30. April. Ich muss den 7. April - 14. April abrufen (da keine Ereignisse geplant sind). – cbronson

+0

Wenn Sie klären können, dann tun Sie dies bitte, indem Sie Ihre Frage bearbeiten. Können Sie auch den Code bereitstellen, mit dem Sie versucht haben? die Datenstruktur mit Beispieldaten? – trincot

Antwort

1

Hier ist eine Lösung, die von/nach Perioden gibt, die frei sind:

// Helper function 
 
function addDays(date, days) { 
 
    return new Date(date.getTime() + days * 24*60*60*1000); 
 
} 
 

 
// Main function 
 
function gaps(period, events) { 
 
    events = events.slice(0).filter(function (a) { 
 
     // Exclude events which are outside the main period 
 
     return a.to >= period.from && a.from <= period.to; 
 
    }).sort(function (a, b) { 
 
     // Sort events by their starting date 
 
     return a.from - b.from; 
 
    }); 
 
    var result = events.reduce(function (result, curr) { 
 
     if (curr.from - result.free > 0) { 
 
      // gap found 
 
      result.gaps.push({ 
 
       from: result.free, 
 
       to: addDays(curr.from, -1) 
 
      }); 
 
     } 
 
     if (curr.to - result.free >= 0) { 
 
      // first free day is after this event 
 
      result.free = addDays(curr.to, 1) 
 
     } 
 
     return result; 
 
    }, { gaps: [], free: period.from }); 
 
    // Potentially add gap between last event end period-end 
 
    if (period.to - result.free >= 0) { 
 
     result.gaps.push({ 
 
      from: result.free, 
 
      to: period.to 
 
     }); 
 
    } 
 
    return result.gaps; 
 
} 
 

 

 
// Sample data: 
 

 
var period = { 
 
    from: new Date('2016-01-01'), 
 
    to: new Date('2016-12-31') 
 
}; 
 

 
var events = [ 
 
    { from: new Date('2016-02-01'), to: new Date('2016-02-29') }, 
 
    { from: new Date('2016-03-01'), to: new Date('2016-03-15') }, 
 
    { from: new Date('2016-04-16'), to: new Date('2016-04-30') }, 
 
]; 
 

 
// Call to function 
 
var res = gaps(period, events); 
 

 
// Output in snippet 
 
document.write('<pre>' + JSON.stringify(res, null, 4));

2

Ich gebe Ihnen nur einen Algorithmus, weil die endgültige Implementierung von Ihrem Code abhängt.

var aprilAvailableDays = [true, true, true, etc...] // a boolean for each day 

aprilEvents.forEach(function (event) { 
    for (var i = event.startDay; i <= event.endDay; i++) { 
     aprilAvailableDays[i] = false; 
    } 
}); 
+2

Die einfachste Lösung ist oft auch die einfachste. Füllen Sie ein Array aller verfügbaren Daten auf, und markieren Sie das Datum bei der Eingabe jedes Datums als nicht verfügbar, wenn es im hinzuzufügenden Bereich liegt. Sie können vorab prüfen, ob eines dieser Daten bereits belegt ist, bevor Sie es hinzufügen. Einfach und elegant. – MyStream

+1

Wow, ich habe das wirklich übertrieben.Vielen Dank für deine Hilfe! – cbronson

Verwandte Themen