Aller au contenu

Messages recommandés

Posté(e)

Salut à tous,

je me suis aperçu que je suis tombé souvent sur ce problème,

mais je l'ai toujours contournée, jamais résolu.

 

si j'ai un liste :

(setq maliste '((1 2)(1 2)) )

et que je veux savoir si ses membres sont égaux:

je ne peux pas faire:

(apply '= maliste)

car j'aurai 1 : fonction inconnue

 

par contre si j'ai

(setq maliste '('(1 2)'(1 2)) )
(apply '= maliste) marche

 

c'est un cas particulier ou vl-every ne m'arrange pas trop non plus, en fait, je veux juste savoir si la liste (1 2) et déjà quotée ou non.

ce n'est pas urgent, mais vous savez, la curiosité ...

a+

Gégé

----------------------------------------------------------------------

Site: https://www.g-eaux.fr

Blog: http://g-eaux.over-blog.com

Posté(e)

Salut

 

Tu ne te sers pas de la bonne fonction pour comparer deux listes

Par exemple

(= '(1 2) '(1 2))

Retourne nil alors que

(equal '(1 2) '(1 2))

Retourne T

Donc, pour ton test, il faut faire

(setq maliste '((1 2)(1 2)))
(apply 'equal maliste)

 

Pour ce qui est de la fonction quote, tu as cet excelent tuto de (gile)

 

@+

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) (modifié)

mon exemple n'était pas bon,

j'ai en fait plus de 2 listes à comparer.

 

Bonjour Gérald,

 

Au risque de répondre à coté, je ne suis pas sur de comprendre la difficulté que tu exposes..

 

Dans le cas de plus de 2 listes (non constitué de sous liste) ;)

_$ (apply 'and (mapcar '= '(1 2 3) '(4 5 6) '(7 8 9))))
nil
_$ (apply 'and (mapcar '= '(1 2 3) '(1 2 3) '(1 2 3)))
T

 

------ EDIT 1 ----------------------

Et si au moins une de tes listes est doublement "quoté" l'expression retournera nil

_$ (apply 'and (mapcar '= '(1 2 3) ''(1 2 3) '(1 2 3)))
nil

 

Le car de ta liste étant de type SYM:

(type (car ''(1 2 3))) => SYM
(type (car '(1 2 3))) => INT

 

------ EDIT 2 --------------------

c'est un cas particulier ou vl-every ne m'arrange pas trop non plus,

Oupsss j'avais pas lu ceci et cela me fait penser que ma proposition n'est qu'une réécriture de la fonction vl-every...

 

 

 

A+

Modifié par VDH-Bruno

Apprendre => Prendre => Rendre

Posté(e)

Salut Bruno,

 

J'ai vraiment un mal fou à bien définir le problème, du coup mes réponses ne seront peut-être pas très claire

Dans le cas de plus de 2 listes (non constitué de sous liste) ;)

_$ (apply 'and (mapcar '= '(1 2 3) '(4 5 6) '(7 8 9))))

Oui, c’est une de 3 solutions de lee mac :

(defun every1 ( prd ls1 ls2 )
   (or (not ls1) (not ls2)
       (and (prd (car ls1) (car ls2)) (every1 prd (cdr ls1) (cdr ls2)))
   )
)
(defun every2 ( prd ls1 ls2 )
   (apply 'and (mapcar 'prd ls1 ls2))
)
(defun every3 ( prd ls1 ls2 / x y )
   (while (and (setq x (car ls1)) (setq y (car ls2)) (prd x y))
       (setq ls1 (cdr ls1)
             ls2 (cdr ls2)
       )
   )
   (or (not ls1) (not ls2))
)

Elles ne résolvent rien au problème que j’ai avec vl-every, mais c’est intéressant

Et si au moins une de tes listes est doublement "quoté" l'expression retournera nil

_$ (apply 'and (mapcar '= '(1 2 3) ''(1 2 3) '(1 2 3)))
nil

En fait, ce que j’entendais par double quote, c’est ça :

’(‘(1 2 3) ‘(1 2 3) ‘(1 2 3))

 

Dans le message suivant je vais essayer de vous faire comprendre la problématique qui m’ait apparue.

A+

Gégé

----------------------------------------------------------------------

Site: https://www.g-eaux.fr

Blog: http://g-eaux.over-blog.com

Posté(e)

re salut à tous,

en fait le problème que j'ai rencontré, c'est un problème de parcours de liste par variable "déléguée"

c'est le problème du mapcar, et du vl-every

 

Un petit rappel:

Commande: (setq a '('( 1 2)))
((QUOTE (1 2)))
Commande: (setq b '(( 1 2)))
((1 2))
Commande: (setq c (list (list 1 2)))
((1 2))
Commande: (car a)
(QUOTE (1 2))
Commande: (car B)
(1 2)

mais en fait avec vl-every:

Commande: (setq lst '('(1 2) '( 1 2)))
((QUOTE (1 2)) (QUOTE (1 2)))
Commande: (eval (append '(vl-every '= ) lst))
T
Commande: (setq lst '((1 2) ( 1 2)))
((1 2) (1 2))
Commande: (eval (append '(vl-every '= ) lst))
"fonction incorrecte: 1" error success; redéfinir après erreur

 

Donc vl-every n'est utilisable qu'avec un nombre d'argument listes connu à l'avance,

ce qui finalement en limite sérieusement l'interet pour cet usage.

 

parceque bien entendu (je dis ça pour frimer mais je suis tombé dans le panneau)

Commande: (setq lst '((1 2) ( 1 2)))
((1 2) (1 2))
Commande: (mapcar '(lambda (x) (quote x)) lst)
(X X)

Moralité on ne peu surquoter les éléments d'une liste qu'a la main ...

 

Donc je suis arrivé à ça, et franchement je trouve ça pas très beau, ni très efficace, puisque le nombre de sous liste est limité à 1 :

 

;***************************************************************************
;§/listes/compare les elements d'une liste : oui s'ils sont tous identiques/lsp
;retourne nil si lst est vide
;;;Commande: (pw_egal_list '((1 2) 1 "r" '(2 3)))
;;;nil
;;;Commande: (pw_egal_list '((e r) ("e" "r")(1 2 3)))
;;;nil
;;;Commande: (pw_egal_list '('(1 2 3) '(4 5 6) '(7 8 9)))
;;;nil
;;;Commande: (pw_egal_list '('(1 2 3) '(1 2 3) '(1 2 3)))
;;;T
;;;Commande: (pw_egal_list '('(1 2 3) '(1 2 3) '(1 2 3 4)))
;;;T
;;;Commande: (pw_egal_list '((1 2 3) (1 2 3) (1 2 3)))
;;;T
;;;Commande: (pw_egal_list '('(1 2)'(1 2)))
;;;T
;;;Commande: (pw_egal_list '(1 2 3))
;;;nil
;;;Commande: (pw_egal_list '(1 1 1))
;;;T
;;;Commande: (pw_egal_list '((1 2 3) (4 5 6) (7 8 9)))
;;;nil

;;mais atention !

;;;_$ (pw_egal_list '(((1 2) 3) ((1 2) 3) ((1 2) 3)))
;;;nil
;;;_$ (pw_egal_list '(((1) (2) (3))((1) (2) (3))((1) (2) (3)) ))
;;;nil
;;;_$ 


(defun pw_egal_list (lst / lcuted lsample lres tmp toutes_egales)
 
 ;;-------------------------------------------------
;;(toutes_egales '((1 2 3) (4 5 6) (7 8 9))) -> nil
;;(toutes_egales '((1 2 3) (1 2 3) (1 2 3))) -> T
 (defun toutes_egales ( llistes / long i ltmp)
        (setq llistes (mapcar '(lambda (x)
			 (if (= 'quote (car x))
			 (cadr x);_supprime le quote
			 x)
			 ) llistes))
   
 (setq long (length (car llistes)))
 (setq i 0)
      (while (and (< i long)
	   (apply '= (mapcar '(lambda (x) (nth i x)) llistes))
	   )
 (setq i (+ 1 i))
      )
 (if (= i long)
	T
	nil
	)
 )
 ;;-------------------------------------------------
 (if lst
   (cond
     ((= (length lst) 1)		;_un seul élément
      T
     )
     ;;membres tous des listes
     ((apply '= (cons t (setq tmp (mapcar 'listp lst))));_ (apply '= (cons t (setq tmp (mapcar 'listp '((1 1)(2 2)))))) -> T		   
      (and (pw_egal_list (mapcar 'length lst));_de même longueur
    (toutes_egales lst);_chaque élément identique
    ;;(eval (append '(vl-every '= ) lst)));_ne marche pas car les sous listes ne sont pas quotées
    )
     )
     ;;membres aucun n'est une liste
     ((apply '= (cons nil tmp))
      (apply '= lst)
     )
     ;;mélange de liste et autre
     (t
      nil
     )
   )
   nil
 )
)

 

a+

Gégé

----------------------------------------------------------------------

Site: https://www.g-eaux.fr

Blog: http://g-eaux.over-blog.com

Posté(e)

Re salu,

c'est en rédigeant ma réponse que m'est enfin apparu la solution, si simple!

j'étais resté bloqué sur le fait qu'equal n'accepte que 2 argument

(defun pw_egal_list (lst / i long)
 (setq long (length lst))
 (setq i 0)
 (while (and (< i (- long 1))
      (equal (nth i lst)
	     (nth (+ 1 i) lst)
      )
 )
   (setq i (+ 1 i))
 )
 (if (= i (- long 1))
   T
   nil
 )
)

et là il n'y a plus de limitations:

Commande: (pw_egal_list '((1 2) 1 "r" '(2 3)))
nil
Commande: (pw_egal_list '((e r) ("e" "r")(1 2 3)))
nil
Commande: (pw_egal_list '('(1 2 3) '(4 5 6) '(7 8 9)))
nil
Commande: (pw_egal_list '('(1 2 3) '(1 2 3) '(1 2 3)))
T
Commande: (pw_egal_list '('(1 2 3) '(1 2 3) '(1 2 3 4)))
nil
Commande: (pw_egal_list '((1 2 3) (1 2 3) (1 2 3)))
T
Commande: (pw_egal_list '('(1 2)'(1 2)))
T
Commande: (pw_egal_list '(1 2 3))
nil
Commande: (pw_egal_list '(1 1 1))
T
Commande: (pw_egal_list '((1 2 3) (4 5 6) (7 8 9)))
nil
Commande: (pw_egal_list '(((1 2) 3) ((4 5) 6) ((7 8) 9)))
nil
Commande: (pw_egal_list '(((1 2) 3) ((1 2) 3) ((1 2) 3)))
T
Commande: (pw_egal_list '(((1) (2) (3))((1) (2) (3))((1) (2) (3)) ))
T

a+

Gégé

----------------------------------------------------------------------

Site: https://www.g-eaux.fr

Blog: http://g-eaux.over-blog.com

Posté(e)

Re,

 

Au vu de la nature de tes listes, effectivement comme suggéré par Patrick_35 je préférerais la fonction equal à =

 

Sinon pour le retour sur le point suivant:

re salut à tous,

en fait le problème que j'ai rencontré, c'est un problème de parcours de liste par variable "déléguée"

c'est le problème du mapcar, et du vl-every

 

Un petit rappel:

Commande: (setq a '('( 1 2)))
((QUOTE (1 2)))
Commande: (setq b '(( 1 2)))
((1 2))
Commande: (setq c (list (list 1 2)))
((1 2))
Commande: (car a)
(QUOTE (1 2))
Commande: (car B)
(1 2)

mais en fait avec vl-every:

Commande: (setq lst '('(1 2) '( 1 2)))
((QUOTE (1 2)) (QUOTE (1 2)))
Commande: (eval (append '(vl-every '= ) lst))
T
Commande: (setq lst '((1 2) ( 1 2)))
((1 2) (1 2))
Commande: (eval (append '(vl-every '= ) lst))
"fonction incorrecte: 1" error success; redéfinir après erreur

 

Donc vl-every n'est utilisable qu'avec un nombre d'argument listes connu à l'avance,

ce qui finalement en limite sérieusement l'interet pour cet usage.

 

Pour appliquer vl-every à une liste d'argument variable, la bonne syntaxe est la suivante:

 
_$ (setq lst '((1 2) ( 1 2)))
((1 2) (1 2))
_$ (apply 'vl-every (cons '= lst))
T

 

A+ Bruno

Apprendre => Prendre => Rendre

Posté(e)

Salut,

 

Pour appliquer vl-every à une liste d'argument variable, la bonne syntaxe est la suivante:

 
_$ (setq lst '((1 2) ( 1 2)))
((1 2) (1 2))
_$ (apply 'vl-every (cons '= lst))
T

 

A+ Bruno

En effet,

c'est incroyable, tout mon problème vient d'avoir confondu la syntaxe d'eval et d'apply !

et plus j'ai pataugé, plus la confusion m'a embrouillé !

merci

A+

Gégé

----------------------------------------------------------------------

Site: https://www.g-eaux.fr

Blog: http://g-eaux.over-blog.com

Posté(e)

c'est incroyable, tout mon problème vient d'avoir confondu la syntaxe d'eval et d'apply !

et plus j'ai pataugé, plus la confusion m'a embrouillé !

merci

 

Oui j'ai vu ça, comme quoi patauger ç'arrive même aux meilleurs, pour s'amuser et tester si on est au point avec quote et eval, un exercice amusant consiste à réécrire une vraie fonction apply

 

 

Commande: (setq lst '((1 2) ( 1 2)))
((1 2) (1 2))
Commande: (mapcar '(lambda (x) (quote x)) lst)
(X X)

Moralité on ne peu surquoter les éléments d'une liste qu'a la main ...

 

 

Si si il est possible de "surquoter" les éléments d'une liste

(mapcar 'quote lst)

((quote (1 2)) (quote (1 2)))

EDIT du 17/05/2017: pour la bonne syntaxe voir code réponse 14

 

Dans ton expression précédente tu as "quoté" l'argument de ta fonction anonyme et non les éléments de ta liste

 

A+ Bruno

Apprendre => Prendre => Rendre

Posté(e)

Salut,

 

Si si il est possible de "surquoter" les éléments d'une liste

_$ (mapcar 'quote  lst)
((quote (1 2)) (quote (1 2)))

Dans ton expression précédente tu as "quoté" l'argument de ta fonction anonyme et non les éléments de ta liste

 

Effectivement, car j'avais choisi un teste combinant des sous-listes surquotées et d'autre non,

donc je passais par un lambda pour tester l'existence ou non de ce quote,

ce qui était d’ailleurs ma question initiale ...

 

ce sont des problèmes mile fois vus, mais ils finissent par s'oublier ...

 

a+

Gégé

----------------------------------------------------------------------

Site: https://www.g-eaux.fr

Blog: http://g-eaux.over-blog.com

Posté(e)

ce sont des problèmes mile fois vus, mais ils finissent par s'oublier ...

 

Re,

 

Oui des problèmes qui finissent par s'oublier car effectivement je me souviens maintenant d'une discussion ou tu avais soulevé un problème avec ce double quote + mapcar

 

Ce qui m'avait fait préféré cette écriture plus robuste:

_$ (mapcar '(lambda (x) (list 'quote x)) '(A B C D E))
((QUOTE A) (QUOTE B) (QUOTE C) (QUOTE D) (QUOTE E))

 

Discution que tu peux retrouver ici -> quote quote

 

A+ Bruno

Apprendre => Prendre => Rendre

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é