Fraid Posté(e) le 4 juin 2018 Posté(e) le 4 juin 2018 Merci, Gile, je commence à comprendre mon erreur,je vais refaire des essais en le plaçant différemment et peux etre 2 fois comme le cddr.Car si cette dernière fonctionne, c'est pour moi une pirouette (suis habitué :(rires forts): ).Dans le sens que c'est grâce au placement de l’élément dans la liste, mais pas grâce à son contenu.Si on ne voulais pas un dossier contenant temp par exemple, la on est pas bien...Je suis loin d’être un perfectionniste, mais ce genre de challenge sont de bon prétexte didactique.A plus tard pour une nouvelle version. (si je m'en sort, vais pas passé l'été la dessus non plus...) https://github.com/Fraiddd
Fraid Posté(e) le 4 juin 2018 Posté(e) le 4 juin 2018 bon, quelque seconde de reflexion, en fait suffit d'utiliser le filtre de vl-directory-files, sujet clos. https://github.com/Fraiddd
Patrick_35 Posté(e) le 5 juin 2018 Posté(e) le 5 juin 2018 Bonjour à tous Ma version(defun rch_che(rep) (cons rep (mapcar '(lambda(x) (rch_che (if (= (substr rep (strlen rep) 1) "\\") (strcat rep x) (strcat rep "\\" x) ) ) ) (if (= (substr rep (strlen rep) 1) "\\") (vl-directory-files rep "*.*" -1) (cddr (vl-directory-files rep "*.*" -1)) ) ) ) ) @+ Les Lisps de PatrickLe but n'est pas toujours placé pour être atteint, mais pour servir de point de mire.Joseph Joubert, 1754-1824
bonuscad Posté(e) le 5 juin 2018 Posté(e) le 5 juin 2018 Je remet un code publié en 2006: comment trouver un fichier depuis un lisp L'optimisation est peut être possible..., mais là j'ai pas trop le temps! (defun extract_folder (lst_fold / l_dir l) (setq l_dir '()) (foreach n lst_fold (setq l (vl-directory-files n nil -1)) (if (eq (car l) ".") (setq l (cddr l)) ) (cond (l (setq l_dir (append (mapcar '(lambda (x) (strcat n x "/") ) l ) l_dir ) ) ) ) ) l_dir ) (defun c:where_file ( / disk_unit folder_name file2find folder_list) (setq disk_unit (getstring T "\nUnité de disque? : ") folder_name (strcat disk_unit (vl-string-translate "\\" "/" (getstring T "\nDémarrer du dossier? : "))) file2find (getstring T "\nFichier à trouver? : ") folder_list (list folder_name) ) (textscr) (if (vl-directory-files folder_name file2find 1) (princ (strcat "\nFichier " file2find " trouvé dans le dossier " (strcase (vl-string-translate "/" "\\" folder_name)))) ) (while (setq folder_list (extract_folder folder_list)) (foreach n folder_list (if (vl-directory-files n file2find 1) (princ (strcat "\nFichier " file2find " trouvé dans le dossier " (strcase (vl-string-translate "/" "\\" n)))) ) ) ) (prin1) ) Choisissez un travail que vous aimez et vous n'aurez pas à travailler un seul jour de votre vie. - Confucius
(gile) Posté(e) le 5 juin 2018 Auteur Posté(e) le 5 juin 2018 @bonucad, (très) intéressant, mais ça ne répond pas précisément à la demande. @Patrick_35, il me semble que le test :if (= (substr rep (strlen rep) 1) "\\") ...)n'est indispensable qu'au premier appel. Ceci dit, ta réponse répond parfaitement à la question reformulée réponse #10, il ne reste plus maintenant qu'à "aplatir" la liste pour répondre à la demande originale. Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
Patrick_35 Posté(e) le 6 juin 2018 Posté(e) le 6 juin 2018 Salut Oui, mais avec une récursive, difficile de faire autrement, à moins de créer une fonction comme ma 1ere version.J'ai pensé remettre la liste à plat, et cela revient à la demande initiale. @+ Les Lisps de PatrickLe but n'est pas toujours placé pour être atteint, mais pour servir de point de mire.Joseph Joubert, 1754-1824
(gile) Posté(e) le 6 juin 2018 Auteur Posté(e) le 6 juin 2018 Je vais donner ma réponse. Afin de ne pas alourdir le code, on considère que le nom de dossier passé comme argument à la fonction récursive ne se termine pas par le séparateur de dossier (vl-string-right-trim "\\" "C:\\Temp\\dossier racine\\"). Pour répondre à la question reformulée réponse #10, je dois faire une fonction qui retourne une liste qui décrit l'arborescence.Dans cette liste, un dossier est représenté par une liste contenant le chemin du dossier et les sous-dossiers qu'il contient représentés de la même façon (algorithme récursif).Ma réponse est semblable à celle de Patrick_35 (l'utilisation de vl-remove plutôt que cddr permet de traiter aussi les lecteurs). (defun GetFolderTree (dir) (cons dir (mapcar '(lambda (x) (GetFolderTree (strcat dir "\\" x)) ) (vl-remove "." (vl-remove ".." (vl-directory-files dir nil -1) ) ) ) ) ) (GetFolderTree (vl-string-right-trim "\\" "C:\\Temp\\dossier racine\\")) renvoie :("C:\\Temp\\dossier racine" ("C:\\Temp\\dossier racine\\Dossier 1" ("C:\\Temp\\dossier racine\\Dossier 1\\Sous dossier 1.1" ("C:\\Temp\\dossier racine\\Dossier 1\\Sous dossier 1.1\\Bidule") ("C:\\Temp\\dossier racine\\Dossier 1\\Sous dossier 1.1\\Truc" ("C:\\Temp\\dossier racine\\Dossier 1\\Sous dossier 1.1\\Truc\\Machin") ) ) ("C:\\Temp\\dossier racine\\Dossier 1\\Sous dossier 1.2") ) ("C:\\Temp\\dossier racine\\Dossier 2" ("C:\\Temp\\dossier racine\\Dossier 2\\Sous dossier 2.1") ("C:\\Temp\\dossier racine\\Dossier 2\\Sous dossier 2.2") ) ) Pour répondre à la question originale et obtenir une simple liste de chemins, il faut "aplatir" cette liste de sous-liste. Si on prend un branche simple : ("C:\\Temp\\dossier racine\\Dossier 2" ("C:\\Temp\\dossier racine\\Dossier 2\\Sous dossier 2.1") ("C:\\Temp\\dossier racine\\Dossier 2\\Sous dossier 2.2") ) elle a été obtenue par l'évaluation de :(cons "C:\\Temp\\dossier racine\\Dossier 2" (list '("C:\\Temp\\dossier racine\\Dossier 2\\Sous dossier 2.1") '("C:\\Temp\\dossier racine\\Dossier 2\\Sous dossier 2.2") ) )où (list ...) est le résultat du (mapcar ...)Pour "aplatir" cette liste, il suffit d'appliquer append à la liste :(cons "C:\\Temp\\dossier racine\\Dossier 2" (apply 'append (list '("C:\\Temp\\dossier racine\\Dossier 2\\Sous dossier 2.1") '("C:\\Temp\\dossier racine\\Dossier 2\\Sous dossier 2.2") ) ) )Il suffit donc d'ajouter (apply 'append ...) dans la fonction GetFolderTree pour aplatir récursivement mon arbre :(defun GetFolders (dir) (cons dir (apply 'append (mapcar '(lambda (x) (GetFolders (strcat dir "\\" x)) ) (vl-remove "." (vl-remove ".." (vl-directory-files dir nil -1) ) ) ) ) ) ) Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
Patrick_35 Posté(e) le 7 juin 2018 Posté(e) le 7 juin 2018 Il suffit donc d'ajouter (apply 'append ...) dans la fonction GetFolderTree pour aplatir récursivement mon arbre :Ben oui, il faut s'habituer à utiliser plus souvent apply. @+ Les Lisps de PatrickLe but n'est pas toujours placé pour être atteint, mais pour servir de point de mire.Joseph Joubert, 1754-1824
x_all Posté(e) le 7 juin 2018 Posté(e) le 7 juin 2018 ho punaise... j'ai du boulot... pour mettre en application ces figures de styles dans mon projet.Quand on a les mains dans le cambouis, on a pas ce genre de réflexe spontanément. (à mon niveau ). Encore un merci à (gile) pour la leçon de choses récursives Du coup sans me changer fondamentalement l'algo, il faut que je révise ces apply, mapcar et compagnie. Je multiplie les boucles imbriquées il y a moyen de les compacter pas mal. quelques trucs sur autocad
VDH-Bruno Posté(e) le 15 juin 2018 Posté(e) le 15 juin 2018 Bonjour, Très rapidement, juste pour le plaisir de proposer une autre écriture récursive sur la façon de parcourir une arborescence, si on ne veut pas passer par des solutions écrites avec mapcar (très en retard sur le challenge, des versions sont déjà proposé par Patrick_35 & (gile)). (defun GetFolders (dir / directory files) (defun directory (dir) (cons dir (files (vl-remove "." (vl-remove ".." (vl-directory-files dir nil -1))))) ) (defun files (rep) (if rep (append (directory (strcat dir "\\" (car rep))) (files (cdr rep))) ) ) (directory dir) ) A+ Bruno Apprendre => Prendre => Rendre
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