2010-04-29 14 views
5

Potrzebuję obliczyć położenie przecięć między wieloma zakresami dat i liczbę zachodzących na siebie przecięć. Następnie muszę pokazać, które zakresy dat i godzin nakładają się na każdą z tych przecinających się sekcji. Jest to nieco bardziej skomplikowane, więc postaram się wyjaśnić, podając przykład. Pracuję w VB.Net, ale przykłady C# są akceptowalne, jak również pracuję w obu.Oblicz położenie i liczbę przecięć między wieloma zakresami dat/godzin?

Mamy kilka zadań wysokiego ryzyka, które dotyczą tego samego systemu. Poniżej mam trzy przykładowe zadania o nazwie HR1/2/3/4 z datą początkową i końcową.

  • HR1 {06.01.2010 10:00 - 15:00 06.01.2010}
  • HR2 {06.01.2010 11:00 - 18:00 06.01.2010}
  • HR3 {06.01.2010 12:00 - 14:00 06.01.2010}
  • HR4 {06.01.2010 18:00 - 20:00 06.01.2010}

To, czego chcę, aby wynik końcowy był przedstawiony poniżej. Mam problem z opisaniem go w dowolny sposób, ale przez przykład.

  • HRE1 {06.01.2010 10:00 - 06.01.2010 11:00} - Przecina 1
  • {Koniec Czas podziału 1, dla czytelności tylko nie potrzebne w roztworze}
  • HRE1 {1/6/2010 11:00 - 1/6/2010 12:00} - Przecięcie 2
  • HRE2 {1/6/2010 11:00 - 1/6/2010 12:00} - Przecięcie 2
  • {Czas zakończenia Podziel 2, tylko do odczytu, nie jest potrzebny w rozwiązaniu}
  • HRE1 {1/6/2010 12:00 - 1/6/2010 14:00}} - Przecięcie 3
  • HRE2 {1/6/2010 12:00 - 1/6/2010 14:00} - Przecięcie 3
  • HRE3 {1/6/2010 12:00 - 1/6/2010 14:00} - Przecięcie 3
  • {Czas zakończenia podziału 3, dla czytelności tylko nie potrzebne w roztworze}
  • HRE1 {06.01.2010 14:00 - 06.01.2010 15:00} - Przecina 2
  • HRE2 { 1/6/2010 14:00 - 1/6/2010 15:00} - Przecięcie 2
  • {Czas zakończenia podzielony na 4, tylko do odczytu, niepotrzebny w roztworze}
  • HRE2 {1/6/2010 15 : 00 - 1/6/2010 18:00} - Przecięcie 1
  • {Czas zakończenia podziału 5, dla czytelności tylko nie potrzebne w roztworze}
  • HR4 {06/01/2010 18:00 - 1/6/2010 20:00} - Przecina 1

Każda pomoc Byłbym bardzo doceniony.

+1

Czy możesz rozwiązać problem za * dwa * przedziały czasu? –

Odpowiedz

5
var timePoints = (from r in ranges select r.Start) 
    .Concat(from r in ranges select r.End) 
    .Distinct().OrderBy(dt => dt).ToArray(); 

var intersections = from i in Enumerable.Range(0, timePoints.Length - 1) 
        let start = timePoints[i] 
        let end = timePoints[i + 1] 
        from range in ranges 
        where range.Start <= start && range.End >= end 
        select new { Range = range, Start = start, End = end }; 

EDIT: Zmodyfikowany kod, który liczy skrzyżowań:

var timePoints = (from r in ranges select r.Start) 
    .Concat(from r in ranges select r.End) 
    .Distinct().OrderBy(dt => dt).ToArray(); 

var intersectionGroups = from i in Enumerable.Range(0, timePoints.Length - 1) 
         let start = timePoints[i] 
         let end = timePoints[i + 1] 
         select new 
         { 
          Start = start, 
          End = end, 
          Ranges = 
           from range in ranges 
           where range.Start <= start && range.End >= end 
           select range 
         }; 

var intersections = from intGroup in intersectionGroups 
        let count = intGroup.Ranges.Count() 
        from range in intGroup.Ranges 
        select new 
        { 
         Range = range, 
         Start = intGroup.Start, 
         End = intGroup.End, 
         Count = count 
        }; 

ja nie wiem, co chcesz zrobić z wyniku, ale może być lepiej użyć intersectionGroups zamiast intersections .

+0

WOW!Jest to bardzo zbliżone do tego, czego szukam. Na początku nie dostałem, ale po przejściu przez to w VS miało sens po minucie. Przyszło mi na myśl dwie małe rzeczy, a jedna to moja wina, ponieważ nie umieściłem jej w oryginalnym poście. Po pierwsze, nie mówi mi, jak wiele innych zakresów pokrywają się z nim. Tak więc dla przedziału czasowego 11:00 do 12:00 wartość wynosiłaby 2. Może to dodatkowa właściwość o nazwie OverlapCount lub coś podobnego. Po drugie: tak nie wspominałem. Elementy znajdujące się w tablicy, które się nie nakładają, są usuwane. Czy istnieje sposób, w jaki możemy je zatrzymać? Dodałem to do postu. – Peter

+0

Mój kod nie upuszcza zakresów, które nie pokrywają się z niczym (np. HR4 w twoim przykładzie). Spojrzę na rachunki. – svick

+0

svick, że mój przyjaciel jest rzeczą piękną. Właściwie opracowałem rozwiązanie problemu przed wysłaniem, ale było tak strasznie, że wiedziałem, że musi istnieć proste rozwiązanie. Po raz kolejny linq oszczędza dzień. Jeszcze raz dziękuję za pomoc. – Peter

Powiązane problemy