algorithme récursif pour coalescent / effondrement liste des dates dans des plages

voix
1

Étant donné une liste de dates

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 récursif (pseudo-code que je peux traduire dans une fonction personnalisée FileMaker) pour produire une liste des gammes, à savoir

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é et dédupliquées. Je l'ai essayé à partir à la fois la première valeur et avant de travail, et la dernière valeur et de travailler en arrière, mais je ne peux pas sembler juste pour le faire fonctionner. Avoir un de ces jours frustrant ... Ce serait bien si la signature était quelque chose comme

CollapseDateList( dateList, separator, ellipsis )

:-)

Créé 18/05/2010 à 13:58
source utilisateur
Dans d'autres langues...                            


2 réponses

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

Je suppose que vous avez une fonction qui vous indique si deux dates sont consécutives ou non.

Créé 18/05/2010 à 15:09
source utilisateur

voix
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, le calcul de la date à partir de la dernière date (droit le plus mot) dans une valeur. De cette façon, il peut décider de quand vérifier si la valeur suivante est toujours partie de la première plage, ou marquer la première gamme comme cela se fait et se concentrer sur le reste des valeurs. Hope it helps 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 )
      ) 
    )
  )
)
Créé 18/05/2010 à 16:26
source utilisateur

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more