Une autre question : je voudrais récupérer tous les éléments d'une liste
satisfaisant une certaine condition. Comme find-if, sauf que je les
voudrais tous plutôt que seulement le premier. Et je n'ai pas trouvé une
fonction aussi simple que find-if pour ça...
Un exemple : dans une liste contenant des sous-listes, je voudrais
récupérer les sous-listes commençant par 4 :
((1 3) (4 6) (4 9))) -> ((4 6) (4 9))
J'ai écrit ça, mais c'est un peu long :
(setf liste (list (list 1 3) (list 4 6) (list 4 9)))
(setf liste-res nil)
(dolist (sous-liste liste)
(when (equal (first sous-liste) 4)
(setf liste-res (push (second sous-liste) liste-res))))
(setf liste-res (nreverse liste-res))
(print liste-res)
On peut faire une version avec map/mapc plutôt qu'avec dolist si j'ai
bien compris, mais ce n'est pas tellement plus simple. Et il me semble
me souvenir que loop permet aussi ça, mais ce ne sera pas beaucoup mieux...
Il n'y a rien de comparable à find-if mais qui collecte tous les éléments ?
Merci
Sylvain
> Bonjour
>
> Une autre question : je voudrais récupérer tous les éléments d'une
> liste satisfaisant une certaine condition.
Autrement dit, tu voudrais enlever de cette liste tous les éléments
qui ne satisfont pas cette condition.
Voir : REMOVE-IF-NOT
> Un exemple : dans une liste contenant des sous-listes, je voudrais
> récupérer les sous-listes commençant par 4 :
> ((1 3) (4 6) (4 9))) -> ((4 6) (4 9))
>
> J'ai écrit ça, mais c'est un peu long :
>
> (setf liste (list (list 1 3) (list 4 6) (list 4 9)))
> (setf liste-res nil)
On ne sait pas trop ce que ça fait d'assigner une variable qui n'est
pas déclarer. Ça peut avoir des effets surprenants. As tu lu le
manuel de l'implémentation que tu utilise ? Qu'en disent-ils ?
Dans le doute, du code portable définirait des variables globales (qui
sont aussi spéciales):
(defparameter *liste * (list (list 1 3) (list 4 6) (list 4 9)))
(defparameter *liste-res* '()) ; une liste s'écrit avec des parentheses.
...
ou utiliserait des variables locales:
(let ((liste (list (list 1 3) (list 4 6) (list 4 9)))
(liste-res '()))
...)
Donc:
(let ((liste (list (list 1 3) (list 4 6) (list 4 9))))
(remove-if-not (lambda (sublist) (= 4 (first sublist))) liste))
Mais dans ce cas, il est plus simple d'enlever les sous listes dont 4
n'est pas le premier élément:
(let ((liste (list (list 1 3) (list 4 6) (list 4 9))))
(remove 4 liste :key (function first) :test (function /=)))
--
__Pascal Bourguignon__
Je n'ai pas lu le manuel :( .
En pratique ça marche avec CLisp et SBCL que j'utilise.
Mais de toutes façons je ne fais ça que pour des tests de quelques
lignes, sinon j'utilise des variables locales. Il s'agissait d'un
exemple simple, juste un test de bout de code avant de l'intégrer dans
une fonction.
Merci pour les exemples, j'ai réussi.