algoritmo recursivo para la coalescencia / lista de colapso de las fechas en rangos
-
27-09-2019 - |
Pregunta
Dada una lista de fechas
12/07/2010
13/07/2010
14/07/2010
15/07/2010
12/08/2010
13/08/2010
14/08/2010
15/08/2010
19/08/2010
20/08/2010
21/08/2010
Estoy buscando punteros hacia un algoritmo recursivo (pseudocódigo cual puede traducirse en una función personalizada de FileMaker) para producir una lista de rangos, es decir.
12/07/2010 to 15/07/2010, 12/08/2010 to 15/08/2010, 19/08/2010 to 20/08/2010
La lista está clasificado previamente y de-duplicado. He tratado a partir de tanto el primer valor y trabajando hacia delante, y el último valor de trabajo y hacia atrás pero simplemente parece que no puede conseguir que funcione. Tener uno de esos días frustrantes ... Sería bueno si la firma fue algo así como
CollapseDateList( dateList, separator, ellipsis )
: -)
Solución
La rutina principal sería algo como esto:
List<String> list = new ArrayList<String>();
String firstDate = dateList[0];
String lastDate = dateList[0];
String currentDate = dateList[0];
for (int i = 1; i < dateList.length(); i++) {
if (dateDiff(dateList[i], currentDate) == 1) {
lastDate = dateList[i];
} else {
list.add(firstDate + separator + lastDate);
firstDate = dateList[i];
lastDate = dateList[i];
}
currentDate = dateList[i];
}
list.add(firstDate + separator + lastDate);
Estoy suponiendo que tiene alguna función que le indica si dos fechas consecutivas o no.
Otros consejos
Este es el código de FileMaker recursivo que hace el trabajo. El enfoque básico es hacer la sustitución en su lugar, en caso necesario calcular la fecha de la última fecha (la mayoría palabra correcta) dentro de un valor. De esa manera se puede decidir cuándo debe comprobar si el siguiente valor sigue siendo parte de la primera gama, o marcar el primer rango que hacer y centrarse en el resto de los valores. Espero que ayuda a otra persona.
// CollapseDateList( dates, comma, dash)
Let(
countDates = ValueCount ( dates );
If (
countDates < 2 ; dates; // return the dates we've been given...
Let(
[
start_date = GetAsDate( LeftWords( GetValue ( dates ; 1 ); 1 ) );
date_1 = GetAsDate( RightWords( GetValue ( dates ; 1 ); 1 ) );
date_2 = GetAsDate( GetValue ( dates ; 2 ) );
date_3 = GetAsDate( GetValue ( dates ; 3 ) );
dv_1 = GetAsNumber( date_1 );
dv_2 = GetAsNumber( date_2 );
dv_3 = GetAsNumber( date_3 );
twoFollowsOne = (dv_2 = dv_1 + 1);
threeFollowsTwo = (dv_3 = dv_2 + 1)
];
// compare dates
Case(
// only two dates in list
countDates = 2;
if (
twoFollowsOne;
start_date & dash & date_2;
GetValue ( dates ; 1 ) & comma & date_2
);
// first three values are sequential
threeFollowsTwo and twoFollowsOne;
CollapseDateList( start_date & dash & date_3 & ¶ & RightValues( dates; countDates - 3 ); comma; dash );
// first two values are sequential only
not threeFollowsTwo and twoFollowsOne;
start_date & dash & date_2 & comma & CollapseDateList( RightValues( dates; countDates - 2 ); comma; dash );
// first two values are not sequential
// default
GetValue ( dates ; 1 ) & comma & CollapseDateList( RightValues( dates; countDates - 1 ); comma; dash )
)
)
)
)