2010-04-29 14 views
5

Necesito calcular la ubicación de las intersecciones entre varios intervalos de fechas y el número de intersecciones superpuestas. Entonces necesito mostrar qué rangos de fecha/hora se superponen a cada una de esas secciones que se intersectan. Es un poco más complicado que eso, así que haré todo lo posible para explicarlo dando un ejemplo. Estoy trabajando en VB.Net, pero los ejemplos de C# son aceptables y también trabajo en ambos.¿Calcula la ubicación y el número de intersecciones entre múltiples rangos de fecha/hora?

Tenemos varias tareas de alto riesgo que involucran el mismo sistema. A continuación tengo tres trabajos de ejemplo denominados HR1/2/3/4 con fecha/hora de inicio y finalización.

  • HR1 {1/6/2010 10:00 - 1/6/2010 15:00}
  • HR2 {1/6/2010 11:00 - 1/6/2010 18:00}
  • HR3 {1/6/2010 12:00 - 1/6/2010 14:00}
  • HR4 {1/6/2010 18:00 - 1/6/2010 20:00}

Lo que quiero que sea el resultado final se muestra a continuación. Tengo problemas para describirlo de cualquier forma excepto por ejemplo.

  • HRE1 {1/6/2010 10:00 - 1/6/2010 11:00} - Intersects 1
  • {Hora de finalización de Split 1, para facilitar la lectura solamente, no es necesario en solución}
  • HRE1 {1/6/2010 11:00 - 1/6/2010 12:00} - Intersects 2
  • HRE2 {1/6/2010 11:00 - 1/6/2010 12:00} - Intersects 2
  • {Hora de finalización 2, solo para legibilidad, no es necesario en solución}
  • HRE1 {1/6/2010 12:00 - 1/6/2010 14:00} - Intersects 3
  • HRE2 {1/6/2010 12:00 - 1/6/2010 14:00} - Intersects 3
  • HRE3 {1/6/2010 12:00 - 1/6/2010 14:00} - Intersects 3
  • {Hora de finalización de Split 3, para facilitar la lectura solamente, no es necesario en solución
  • } {
  • HRE1 1/6/2010 14:00 - 1/6/2010 15:00} - intersecta 2
  • HRE2 { 1/6/2010 14:00 - 1/6/2010 15:00} - Interseca 2
  • {Hora de finalización División 4, para legibilidad solamente, no es necesario en solución}
  • HRE2 {1/6/2010 15 : 00 - 1/6/2010 18:00} - Intersects 1
  • {Hora de finalización de Split 5, para facilitar la lectura solamente, no es necesario en solución
  • } {
  • HR4 1/6/2010 18:00 - 1/6/2010 20:00} - intersecta 1

Cualquier ayuda sería muy apreciado.

+1

¿Puedes resolver el problema con * dos * intervalos de tiempo? –

Respuesta

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: código modificado que cuenta intersecciones:

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 
        }; 

no sé qué quiere hacer con el resultado, pero puede ser mejor usar intersectionGroups en lugar de intersections .

+0

¡GUAU!Esto está muy cerca de lo que estoy buscando. Al principio no lo entendí, pero después de revisarlo en VS tuvo sentido después de un minuto. Me vienen a la mente dos cosas pequeñas, y una es mi culpa ya que no la puse en la publicación original. Primero, no me dice cuántos otros rangos se superponen. Entonces para el rango de tiempo de 11:00 a 12:00 el valor sería 2. Quizás una propiedad adicional llamada OverlapCount o algo así. Segundo: Este es el caso que no mencioné. Los elementos que están en la matriz que no se superponen a nada se eliminan. ¿Hay alguna manera de mantenerlos? Agregué esto a la publicación. – Peter

+0

Mi código no elimina los rangos que no se superponen con nada (como HR4 en su ejemplo). Echaré un vistazo a los conteos. – svick

+0

svick, que mi amigo es una belleza. De hecho, había desarrollado una solución al problema antes de publicarla, pero era tan horrible que sabía que tenía que haber una solución simple. Una vez más, linq salva el día. Gracias de nuevo por la asistencia svick. – Peter

Cuestiones relacionadas