Aller au contenu

Messages recommandés

Posté(e)

Bonjour,

 

(vl-position) répondait exactement à mon besoin mais a un gros défaut; elle ne retourne que la position du 1er élément trouvé.

Ce que je désire avoir en retour, ce sont les positions multiples de l'élément dans la liste.

Exemple pour:

(setq stuff (list "a" "b" "c" "d" "e" "c" "a"))

que

(vl-position-multi "c" stuff) -> (2 5)

(vl-position-multi "a" stuff) -> (0 6)

(vl-position-multi "b" stuff) -> (1)

(vl-position-multi "f" stuff) -> nil

 

Bien sur, à la différence de vl-position la fonction me retourne une liste d'entier ou nil

 

J'ai bien déjà pondu ça:

 

(defun vl-position-multi (el l / n l_id l_n)
 (setq
   n 0
   l_id (mapcar '(lambda (x) (equal x el)) l)
 )
 (repeat (length l_id)
   (if (car l_id) (setq l_n (cons n l_n)))
   (setq n (1+ n) l_id (cdr l_id))
 )
 (reverse l_n)
)

 

Pour le peu de test que j'ai effectué, ca à l'air correct.

Mais je serais curieux d'avoir d'autres versions (les pros de la récursivité) ou de manière plus concise...

 

Si ça vous dit!

Choisissez un travail que vous aimez et vous n'aurez pas à travailler un seul jour de votre vie. - Confucius

Posté(e)

(setq stuff (list "a" "b" "c" "d" "e" "c" "a" "a" "a" "a" "c"))

(defun truc(ctl stuff / i)
 (cond((setq i(vl-position ctl stuff))
       (setq lst(cons(+ i (if lst(1+ (car lst))0)) lst))
       (truc ctl(cdr(member ctl stuff)))
       ))
 lst)
(setq lst nil)(reverse(truc "c" stuff))
(setq lst nil)(reverse(truc "a" stuff))

 

Code honteux mais pas d'itération.

Bureau d'études dessin.

Spécialiste Escaliers

Développement - Formation

 

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

Merci de ta contribution Tramber,

 

La récursivité est bien, j'avais songé aussi au (cdr (member)) mais ça nécessite de compter, ce que tu fais d'ailleurs avec ta variable (pas très catholique) lst.

Choisissez un travail que vous aimez et vous n'aurez pas à travailler un seul jour de votre vie. - Confucius

Posté(e)

Je t'en prie.

En + propre :

(defun vl-position-multi (el l / lst)
 (defun truc(ctl stuff / i)
   (cond((setq i(vl-position ctl stuff))
  (setq lst(cons(+ i (if lst(1+ (car lst))0)) lst))
  (truc ctl(cdr(member ctl stuff)))
  ))
   lst)
 (reverse(truc el l)))

C'est pas si mal !

Bureau d'études dessin.

Spécialiste Escaliers

Développement - Formation

 

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

Salut,

 

J'ai tout de suite refermé le lien donné par Patrick_35 pour pouvoir jouer.

 

(defun mpos (p l / i r)
 (setq i 0)
 (foreach x l
   (if	(equal x p)
     (setq r (cons i r))
   )
   (setq i (1+ i))
 )
 (reverse r)
)

 

Maintenant, je vas voir TheSwamp.

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

Posté(e)

mmm'

Je me sens toujours petit dans ces challenges. C'est vrai que j'aime bien aider pour les petits niveaux ou me concentrer sur mes trucs et que je n'ai pas beaucoup pratiqué avec vous.

Tiens, je vois que (gile) tu ne cherches pas à éviter la boucle.

 

Maintenant faudrait voir des benchmarks ... il y en a sur le Swamp mais on aurait peut-être dû y faire des benchmarks avec des listes bien longues et d'autres bien courtes.

Comme souvent, je me demande ce que veulent vraiment dire les benchmarks quand on n'en fait pas plusieurs versions avec toutes les fonctions...

Bureau d'études dessin.

Spécialiste Escaliers

Développement - Formation

 

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

Salut

 

J'ai trouvé un peu de temps pour jouer aussi.

 

Sans ticher et j'ai ensuite regardé plus en détail le lien que j'avais donné. Très proche de la routine index.

 

(defun vl-pat(ele lst / der pos tab)
 (setq der -1)
 (while (setq pos (vl-position ele lst))
   (setq der (+ pos der 1)
  tab (cons der tab)
  lst (cdr (member ele lst))
   )
 )
 (reverse tab)
)

 

@+

Les Lisps de Patrick

Le but n'est pas toujours placé pour être atteint, mais pour servir de point de mire.

Joseph Joubert, 1754-1824

Posté(e)

Après lecture des codes et du lien.

 

La fonction mpos de (gile) est proche de M-position de Tharwat

La fonction vl-pat de Patrick_35 (comme il l'a fait remarqué) est proche de index de Stefan

Cette dernière ce révèle la plus rapide au benchmark (j'ai pas vérifié..., en plus je n'ai pas l'outil!)

 

Comme quoi lorsqu'on cherche une manière concise on se rapproche d'un code commun.

 

Honneur à Tramber qui est le seul (pour l'instant) à avoir proposé une fonction récursive.

 

Pour les benchmarks, tant que les valeurs sont proches cela n'est pas vraiment révélateur à mon avis: Si j'ai le temps de faire un clin d'oeil ;) pour moi c'est kif-kif... je ne fais pas la chasse aux milli-secondes. :P

Choisissez un travail que vous aimez et vous n'aurez pas à travailler un seul jour de votre vie. - Confucius

Posté(e)

Honneur à Tramber qui est le seul (pour l'instant) à avoir proposé une fonction récursive.

Merci

Moi je suis bête commme un mouton. En lisant des challenges (il y a longtemps maintenant car ces derniers temps je ne lisais plus rien), j'avais souvent noté que les plus élégantes et rapides étaient récursives.

Alors j'ai cherché à faire ainsi uniquement.

C'est vrai que le While sur vl-position est tout bête de ce point de vue.

Bureau d'études dessin.

Spécialiste Escaliers

Développement - Formation

 

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

Pour une fois que je ne fais pas une récursive...

 

Tiens, une récursion terminale en F# (on peut tester avec Try F#)

let mpos ele lst = 
   let rec loop i l a =
       match l with
       | []                  -> List.rev a
       | h :: t when h = ele -> loop (i + 1) t (i :: a)
       | h :: t              -> loop (i + 1) t a 
   loop 0 lst []

 

La conversion en (pur) AutoLISP :

(defun mpos (ele lst / loop)
 (defun loop (i l a)
   (cond
     ((null l) (reverse a))
     ((equal ele (car l)) (loop (1+ i) (cdr l) (cons i a)))
     (T (loop (1+ i) (cdr l) a))
   )
 )
 (loop 0 lst nil)
)

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

Posté(e)

ma contribution, sans copier...

 

(defun vl-position-multi (key alist / i x nlist)
 (setq 
   i -1
   alist (mapcar '(lambda (x) (setq i (1+ i)) (cons x i)) alist)
 )
 (foreach x alist
   (if (eq key (car x))
     (setq nlist (cons (cdr x) nlist))
   )
 )
 (reverse nlist)
)

 

Maintenant, je peux regarder. Je constate que ça ressemble à mpos, sauf que la liste est indexée avant de faire le foreach. Je voulais aussi voir si on pouvait mettre un compteur dans un mapcar. A priori, oui !

 

Amicalement

Vincent

C'est au pied du mur que l'on reconnaît le maçon ! (Anonyme)

C’est en restant au pied du mur qu’on ne voit que le mur (Anonyme aussi)

Posté(e)

Zebulon m'a donné une idée avec le mapcar

Donc une autre version plus courte

 

(defun vl-pat2(ele lst)
 (setq i -1)
 (vl-remove nil (mapcar '(lambda(x)(setq i (1+ i))(if (eq x ele) i nil)) lst))
)

 

@+

Les Lisps de Patrick

Le but n'est pas toujours placé pour être atteint, mais pour servir de point de mire.

Joseph Joubert, 1754-1824

Posté(e)

Zebulon m'a donné une idée avec le mapcar

Donc une autre version plus courte

 

(defun vl-pat2(ele lst)
 (setq i -1)
 (vl-remove nil (mapcar '(lambda(x)(setq i (1+ i))(if (eq x ele) i nil)) lst))
)

 

@+

 

Au lieu de numéroter bêtement chaque élément, tu ne numérotes que les représentants de la clé recherchée. Les autres éléments héritent d'un nil que tu enlèves facilement de la liste.

 

Bien vu !

Amicalement

Vincent

C'est au pied du mur que l'on reconnaît le maçon ! (Anonyme)

C’est en restant au pied du mur qu’on ne voit que le mur (Anonyme aussi)

Posté(e)

Pas du jeu !

L'idée du mapcar pour tout faire, dès fois ça suffit ;)

J'aime bien aussi mpos car il n'y a pas de setq

Bureau d'études dessin.

Spécialiste Escaliers

Développement - Formation

 

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

Encore une, assez proche de la dernière de Patrick_35

 

let mpos ele lst =
   let i = ref -1
   List.choose (fun x ->
       i := !i + 1
       if x = ele then Some !i else None) lst

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

Posté(e)

Ben ça y est... J'ai mal à le tête...

 

Mais très instructif... On voit que pour une seule "fonction", il y a plein de méthodes...

Windows 11 / AutoCAD 2024

Sur terre, il y a 10 types de personnes, celles qui comptent en binaire et les autres (developpez.net).
Davantage d'avantages, avantagent davantage (Bobby Lapointe).
La connaissance s'accroît quand on la partage (Socrate).
Tant va la cruche à l'eau que l'habit n'amasse pas mousse avant de l'avoir tué. (Moi)

Posté(e)

(defun vl-pat2(ele lst)
 (setq i -1)
 (vl-remove nil (mapcar '(lambda(x)(setq i (1+ i))(if (eq x ele) i nil)) lst))
)

le nil dans le sinon du if n'est pas forcément nécessaire. Si on ne met rien, le sinon revoie de toute manière nil, pas besoin de le préciser explicitement.

 

(defun vl-pat2(ele lst)
 (setq i -1)
 (vl-remove nil (mapcar '(lambda(x)(setq i (1+ i))(if (eq x ele) i)) lst))
)

 

Du coup, c'est encore plus court :)

 

Amicalement

Vincent

C'est au pied du mur que l'on reconnaît le maçon ! (Anonyme)

C’est en restant au pied du mur qu’on ne voit que le mur (Anonyme aussi)

Posté(e)

(defun vl-pat2(ele lst)
 (setq i -1)
 (vl-remove nil (mapcar '(lambda(x)(setq i (1+ i))(if (eq x ele) i nil)) lst))
)

le nil dans le sinon du if n'est pas forcément nécessaire. Si on ne met rien, le sinon revoie de toute manière nil, pas besoin de le préciser explicitement.

 

(defun vl-pat2(ele lst)
 (setq i -1)
 (vl-remove nil (mapcar '(lambda(x)(setq i (1+ i))(if (eq x ele) i)) lst))
)

 

Du coup, c'est encore plus court :)

 

Amicalement

Vincent

Ah oui, bien vu :D

 

Bravo

 

@+

Les Lisps de Patrick

Le but n'est pas toujours placé pour être atteint, mais pour servir de point de mire.

Joseph Joubert, 1754-1824

Posté(e)

Salut

 

Un sujet à lire

 

@+

 

...c'est encore plus court et ça correspond à la première solution proposée par Lee Mac dans le sujet référencé.

 

Amicalement

Vincent

C'est au pied du mur que l'on reconnaît le maçon ! (Anonyme)

C’est en restant au pied du mur qu’on ne voit que le mur (Anonyme aussi)

  • 4 semaines après...
Posté(e)

smile.gif

(defun test (a s)
 (defun f (a s i)
   (if i
     (cons i (f a s (VL-STRING-SEARCH a s (1+ i))))
   )
 )
 (f a (apply 'strcat s) (vl-position a s)))

 

(test "a"(list "a" "b" "c" "d" "e" "c" "a" "a" "a" "a" "c"))

 

Evgeniy

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é