fabcad Posté(e) le 13 mars 2012 Posté(e) le 13 mars 2012 Bonjour Amis lispeurs, Soit des listes de dates sous la forme : list_dates_debut = ("31/12/2012" "28/10/2011" "01/03/2010" "25/04/2009")) list_dates_fin = ("30/11/2015" "21/08/2013" "01/04/2012" "26/05/2009")) 1- Comment trier ces 2 listes.2- Comment trouver le max et le min sur ces listes de dates. Merci pour votre aide. Fabcad
bryce Posté(e) le 13 mars 2012 Posté(e) le 13 mars 2012 Bonjour, Ma première idée serait de convertir chaque date en un nombre entier (nombre de jours écoulés depuis le 01/01/0000 par exemple) pour faciliter le tri, puis de reconvertir en date ensuite.Quitte à tricher pour simplifier, en considérant que toutes les années comptent 372 jours, et tous les mois comptent 31 jours...Par exemple le 31/12/2012 deviendrait 31+11*31+2011*372 = 748464, et ainsi de suite. :unsure: Edit: si tous les mois ont 31 jours, alors une année en compte 372... Brice, formateur AutoCAD - Inventor - SolidWorks - ZWCad - DraftSight - SketchUp indépendant
VDH-Bruno Posté(e) le 13 mars 2012 Posté(e) le 13 mars 2012 Salut, Pas trop difficile avec la foison de routines laissé par (gile) sur le forum:(defun tridates (lst) (mapcar '(lambda (x) (lst2str (reverse x) "/")) (vl-sort (mapcar '(lambda (x) (reverse (str2lst x "/"))) lst) 'compareList ) ) ) Avec les routines associées suivantes :;; STR2LST ;; Transforme un chaine avec séparateur en liste de chaines ;; ;; Arguments ;; str : la chaine à transformer en liste ;; sep : le séparateur ;; ;; Exemples ;; (str2lst "a b c" " ") -> ("a" "b" "c") ;; (str2lst "1,2,3" ",") -> ("1" "2" "3") ;; (mapcar 'read (str2lst "1,2,3" ",")) -> (1 2 3) (defun str2lst (str sep / pos) (if (setq pos (vl-string-search sep str)) (cons (substr str 1 pos) (str2lst (substr str (+ (strlen sep) pos 1)) sep) ) (list str) ) ) ;; LST2STR ;; Concatène une liste et un séparateur en une chaine ;; ;; Arguments ;; lst : la liste à transformer en chaine ;; sep : le séparateur ;; ;; Exemples ;; (lst2str '(1 2 3) ",") -> "1,2,3" ;; (lst2str '("a" "b" "c") " ") -> "a b c" (defun lst2str (lst sep) (if (cadr lst) (strcat (vl-princ-to-string (car lst)) sep (lst2str (cdr lst) sep) ) (vl-princ-to-string (car lst)) ) ) ;; Compare des listes par la tête ;; http://cadxp.com/index.php?/topic/29470-trier-une-liste/page__p__160087#entry160087 (defun compareList (l1 l2) (if (and (and l1 l2) (= (car l1) (car l2))) (compareList (cdr l1) (cdr l2)) (< (car l1) (car l2)) ) ) Donc pour avoir :1- Comment trier cs 2 listes._$ (setq list_dates_debut (tridates '("31/12/2012" "28/10/2011" "01/03/2010" "25/04/2009"))) ("25/04/2009" "01/03/2010" "28/10/2011" "31/12/2012") $ (setq list_dates_fin (tridates '("30/11/2015" "21/08/2013" "01/04/2012" "26/05/2009"))) ("26/05/2009" "01/04/2012" "21/08/2013" "30/11/2015") 2- Comment trouver le max et le min sur ces listes de dates. _$ (car list_dates_debut);retourne le min "25/04/2009" _$ (car list_dates_fin);retourne le min "26/05/2009" _$ (last list_dates_debut);retourne le max "31/12/2012" _$ (last list_dates_fin);retourne le max "30/11/2015" A+ Apprendre => Prendre => Rendre
(gile) Posté(e) le 13 mars 2012 Posté(e) le 13 mars 2012 Salut, Dans le même esprit que VDH_Bruno, mais qui ne fonctionnera qu'avec des dates formatées : JJ/MM/AAAA. (defun sortDate (lst) (vl-sort lst '(lambda (d1 d2) (if (= (substr d1 7) (substr d2 7)) (if (= (substr d1 4 2) (substr d2 4 2)) (< (substr d1 1 2) (substr d2 1 2)) (< (substr d1 4 2) (substr d2 4 2)) ) (< (substr d1 7) (substr d2 7)) ) ) ) ) on peut aussi définir une fonction de tri par clé (ici sortBy) qui accepte deux arguments : une fonction qui génère une clé pour chaque élément de la liste et la liste à trier.Pour les dates formatées telles que ci-dessus, la fonction génèrera une clé AAAAMMJJ (defun sortBy (fun lst) (setq fun (eval fun)) (vl-sort lst '(lambda (x1 x2) (< (fun x1) (fun x2)))) ) (defun sortDate (lst) (sortBy '(lambda (s) (strcat (substr s 7) (substr s 4 2) (substr s 1 2))) lst) ) Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
fabcad Posté(e) le 13 mars 2012 Auteur Posté(e) le 13 mars 2012 Bonsoir (gile), VDH-Bruno, bryce. Merci pour vos réponses, je vais essayer ceci demain matin pour gérer mes données temporelles de chantier. Bonne soirée, Fabcad
(gile) Posté(e) le 13 mars 2012 Posté(e) le 13 mars 2012 Dans la mêmme veine que la dernière, pour obtenir le minimum ou le maximum sans trier la liste (on ne la parcourt qu'une seule fois). La fonction reduce applique la fonction spécifiée aux deux premiers éléments de la liste. Elle passe ensuite ce résultat dans la fonction avec le troisième élément et ainsi de suite. Enfin, elle retourne le résultat final. Si la fonction d'entrée est 'fun et que les éléments sont (i0...in), alors cette fonction calcule : (fun (... (fun (fun i0 i1) i2) ...) in). Les fonctions minBy et maxBy appellent reduce en comparant les clés générées pour chaque élément de la liste. (defun reduce (fun lst) (if (cdr lst) (reduce fun (cons ((eval fun) (car lst) (cadr lst)) (cddr lst))) (car lst) ) ) (defun minBy (fun lst) (reduce '(lambda (x y) (if (< ((eval fun) y) ((eval fun) x)) y x )) lst) ) (defun maxBy (fun lst) (reduce '(lambda (x y) (if (> ((eval fun) y) ((eval fun) x)) y x )) lst) ) (minBy '(lambda (s) (strcat (substr s 7) (substr s 4 2) (substr s 1 2))) list_dates_debut) retourne la date la pus ancienne, maxBy avec la même expression lambda, la date la plus récente. Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
VDH-Bruno Posté(e) le 14 mars 2012 Posté(e) le 14 mars 2012 (modifié) Merci (gile), c’est très intéressant comme façon de faire :) :) :) Juste une petite suggestion sur la forme, il me semble qu'en ne quotant pas la fonction lambda passé en argument à la fonction sortBy, on doit pouvoir économiser l'expression (setq fun (eval fun)) qui fait un peu symétrique, mais a sans doute le mérite d'être plus conventionnel:(defun sortBy (fun lst) (vl-sort lst '(lambda (x1 x2) (< (fun x1) (fun x2)))) ) (defun sortDate (lst) (sortBy (lambda (s) (strcat (substr s 7) (substr s 4 2) (substr s 1 2)) ) lst ) ) ----------- Edit ----------------En voulant tester, pour minBy & maxBy j'ai le message d'erreur suivant:; erreur: nombre d'arguments insuffisants_$Si j'ai un peu de temps en soirée j'essayerai de regarder plus dans le détail.. A+ Modifié le 14 mars 2012 par VDH-Bruno Apprendre => Prendre => Rendre
(gile) Posté(e) le 14 mars 2012 Posté(e) le 14 mars 2012 J'ai préféré utiliser une fonction "quotée" comme argument pour respecter la syntaxe utilisée par les fonctions LISP natives (mapcar, vl-sort, etc.) L'erreur est due au fait que j'ai utilisé le même symbole (fun) pour les fonctions passées en argument à reduce et minBy/maxBy Utiliser plutôt celles-ci :(defun sortBy (keygen lst) (setq keygen (eval keygen)) (vl-sort lst '(lambda (x1 x2) (< (keygen x1) (keygen x2)))) ) (defun reduce (aggregate lst) (if (cdr lst) (reduce aggregate (cons ((eval aggregate) (car lst) (cadr lst)) (cddr lst))) (car lst) ) ) (defun minBy (keygen lst) (reduce '(lambda (x y) (if (< ((eval keygen) y) ((eval keygen) x)) y x )) lst) ) (defun maxBy (keygen lst) (reduce '(lambda (x y) (if (> ((eval keygen) y) ((eval keygen) x)) y x )) lst) ) Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
VDH-Bruno Posté(e) le 14 mars 2012 Posté(e) le 14 mars 2012 Merci pour la correction, je pensais jeter un œil dessus (en ce moment je suis amateur de cette façon de coder)et finalement j’en suis resté à méditer sur l’intérêt de transmettre en argument des fonctions «quoté», ce que je prenais à tord pour une convention (ou un simple respect de la syntaxe utilisée par les fonctions LISP natives) va un peu plus loin, faut jusque je réussisse à formuler cela de façon claire avant d’en faire un petit topo..A+ Apprendre => Prendre => Rendre
Patrick_35 Posté(e) le 19 mars 2012 Posté(e) le 19 mars 2012 Salut Une autre méthode est de transformer la date au format julien. Après, c'est de la rigolade avec les fonctions min et max.Ci-joint un vieux lisp (que je connais depuis la version 10 au moins) qui permet la convertion du calendrier julien au calendrier grégorien et inversement (peut-être aussi utile pour ceux qui travaille avec Excel). @+julian.lsp Les Lisps de PatrickLe but n'est pas toujours placé pour être atteint, mais pour servir de point de mire.Joseph Joubert, 1754-1824
Messages recommandés
Créer un compte ou se connecter pour commenter
Vous devez être membre afin de pouvoir déposer un commentaire
Créer un compte
Créez un compte sur notre communauté. C’est facile !
Créer un nouveau compteSe connecter
Vous avez déjà un compte ? Connectez-vous ici.
Connectez-vous maintenant