2010-05-18 18 views
1

Compte tenu de la liste des datesalgorithme récursif pour la liste coalescent/effondrement des dates dans des plages

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 

Je cherche des pointeurs vers un algorithme pseudo-code récursif (que je peux traduire en une fonction personnalisée FileMaker) pour la production une liste de plages, c'est-à-dire

12/07/2010 to 15/07/2010, 12/08/2010 to 15/08/2010, 19/08/2010 to 20/08/2010 

La liste est pré-triée et dédupliquée. J'ai essayé de partir à la fois de la première valeur et du travail en avant, et de la dernière valeur et de travailler en arrière, mais je n'arrive tout simplement pas à le faire fonctionner. Avoir un de ces jours frustrant ... Ce serait bien si la signature était quelque chose comme

CollapseDateList(dateList, separator, ellipsis) 

:-)

Répondre

1

La routine principale ressemblerait à quelque chose comme ceci:

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

I Supposons que vous ayez une fonction qui vous indique si deux dates sont consécutives ou non.

+0

Vous ne savez pas comment cela est récursif? – Dycey

+0

@Dycey: Le pseudo-code n'est pas récursif, à moins que vous ne considériez une boucle récursive. –

+0

Ce qui est dommage car je demandais du code récursif (premier mot dans le titre :-))! Je n'étais pas obtus - les fonctions personnalisées FileMaker utilisent un langage fonctionnel de sorte que vous devez utiliser la récursivité à la place des boucles. – Dycey

1

Voici le code FileMaker récursif qui fait le travail. L'approche de base est de faire le remplacement en place, le cas échéant en calculant la date à partir de la dernière date (le plus à droite mot) dans une valeur. De cette façon, il peut décider quand vérifier si la valeur suivante fait toujours partie de la première plage, ou marquer la première plage comme terminée et se concentrer sur le reste des valeurs. J'espère que ça aide quelqu'un d'autre.

// 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) 
    ) 
    ) 
) 
)