Aller au contenu

Messages recommandés

Posté(e)

Bonjour,

 

(vl-string-trim "," ",0,0,0,,,") me permet d'obtenir "0,0,0".

C'est un préalable utile.

 

Dans ce vieux sujet, j'ai demandé de l'aide pour traiter le problème suivant :

 

Soit une chaine de caractères, je veux en retirer tout ce qui n'est pas chiffre entier ou virgules qui les séparent.

 

Le but étant, à terme, de transformer le tout en liste d'entiers.

 

"1" renvoie "1"

"1,2" renvoie "1,2"

"_\oi-_,90,ut5," renvoie ",90,5," -> (vl-string-trim "," ",90,5,") à la fin rend facilement "90,5"

"123,,,51,2" renvoie "123,51,2"

 

J'y arrive bien (et encore !) avec des routines lourdingues mais je me demande s'il n'y a pas de solutions récursives. Comme j'ai un peu le sujet en tête...

On y parle de mécanique mais j'ai l'impression parfois de n'être qu'un chauffeur (si le lisp est le moteur) et ni ingénieur, ni même mécanicien :cool:

 

Alors pourl'instant, j'essaie déjà un bon traitement non récursif :

 

(defun test(nom / lettre compt)
 (setq compt 1)
 (while(and(>(strlen nom)0)(    (if (wcmatch(setq lettre(substr nom compt 1)) "[0-9],[`,]")
     (setq compt(1+ compt))
     (setq nom(vl-string-subst "" lettre nom))
     ))
 nom)

(test "3")
(test "3,2")
(test "3,2.")
(test "..|_3,2.")
(test "3,2,,,1")

 

Seulement voilà, comme le montre le dernier test, je n'ai pas pu traiter efficacement les virgules en trop !

Serait-ce un challenge intéressant d'aller plus loin, et avec une fonction récursive ? ou cela devient-il superflu ?

Autre question, très liée je pense, si je devais éclater cette chaine d'entrée en autant d'éléments d'une liste constituée de caractères simples. La récursivité est mieux adaptée aux listes (!?), non ?

 

Hop

 

Bureau d'études dessin.

Spécialiste Escaliers

Développement - Formation

 

./__\.
(.°=°.)
Posté(e)

Vite fait,

 

Si on veut vraiment faire du récursif, sur les chaînes c'est assez facile avec la concaténation mais le traitement des chaînes est en général assez couteux

 

(defun test (nom / lettre)
 (if (= nom "")
   ""
   (if	(wcmatch (setq lettre (substr nom 1 1)) "[0-9],`,")
     (strcat lettre (test (substr nom 2)))
     (test (substr nom 2))
   )
 )
)

 

On avait vu que le traitement des listes est plus rapide en LISP

 

(defun toto (nom)
 (vl-list->string
   (vl-remove-if-not
     '(lambda (x) (or (= x 44) (      (vl-string->list nom)
   )
 )
)

Gilles Chanteau - gileCAD - GitHub
Développements sur mesure pour AutoCAD

Posté(e)

Je te remercie. et c'est vrai qu'avec vl-list->string et son pendant inverse, le passe-passe est facile.

 

J'étudie cette piste histoire de supprimer les code 44 en doubles (les virgules). C'est mon ultime étape pour cette fonction.

Mais j'avoue que je n'arrive pas à monter cet outil, exemple avec TOTO :

 

(vl-remove-if '(lambda(x y)(= 44 x y))(vl-string->list "3,,4,5")) 

 

Ca n'est peut-être pas si simple.

Bureau d'études dessin.

Spécialiste Escaliers

Développement - Formation

 

./__\.
(.°=°.)
Posté(e)

Si les chaînes ne sont pas trop longues, la différence de rapidité d'exécution entre une solution récursive et vl-remove-if devrait être quasiment insensible.

On peut alors utiliser un drapeau (flag) qui indique si le dernier caractère ajouté était une virgule.

 

(defun toto (str / foo)
 (defun foo (s f / c)
   (cond
     ((= s "") s)
     ((= (setq c (substr s 1 1)) ",")
      (strcat (if (= f 1) "" c) (foo (substr s 2) 1))
     )
     ((wcmatch c "[0-9]") (strcat c (foo (substr s 2) 0)))
     ((foo (substr s 2) f))
   )
 )
 (foo str 0)
)

 

Si tu veux supprimer les virgules à la fin, remplace ((= s "") "") par ((or (= "," s) (= s "") "")

Si tu veux supprimer les virgules au début remplace (foo str 0) pat (foo str 1)

Gilles Chanteau - gileCAD - GitHub
Développements sur mesure pour AutoCAD

Posté(e)

ou itératif :

 

(defun toto (str / flag rslt char)
 (setq	flag 0
rslt ""
 )
 (while (/= str "")
   (cond
     ((= (setq char (substr str 1 1)) ",")
      (if (= flag 0)
 (setq rslt (strcat rslt ",")
       flag 1
 )
      )
     )
     ((wcmatch char "[0-9]")
      (setq rslt (strcat rslt char)
     flag 0
      )
     )
   )
   (setq str (substr str 2))
 )
 rslt
)

Gilles Chanteau - gileCAD - GitHub
Développements sur mesure pour AutoCAD

Posté(e)

Joli ! Tout marche bien. Même en itératif, cela montre que j'aurais pu faire mieux moi-même.

 

(vl-string-trim "," ",0,0,0,,,") me permet d'obtenir "0,0,0".

donc je ne me fais pas de bile pour les virgules avant ou après ! Je passe ce traitement au moment opportun.

 

Hoppla

Bureau d'études dessin.

Spécialiste Escaliers

Développement - Formation

 

./__\.
(.°=°.)

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 compte

Se connecter

Vous avez déjà un compte ? Connectez-vous ici.

Connectez-vous maintenant
×
×
  • Créer...

Information importante

Nous avons placé des cookies sur votre appareil pour aider à améliorer ce site. Vous pouvez choisir d’ajuster vos paramètres de cookie, sinon nous supposerons que vous êtes d’accord pour continuer. Politique de confidentialité