2010-09-18 8 views
0

Je tente d'écrire une fonction de système qui prend une liste de la forme:liste Scheme modification

((#f ((1 1) (2 1))) 
(#f ((1 3) (5 1))) 
(#f ((1 4) (7 1))) 
) 

et supprime toutes les #f pour donner une liste comme:

(((1 1) (2 1)) 
    ((1 3) (5 1)) 
    ((1 4) (7 1)) 
) 

Je essayé le code suivant, mais ne peut pas le faire fonctionner:

(define meth 
    (lambda lst 
    (if (equal? (cdr lst) '()) 
     (cdr (car lst)) 
     (cons (list-ref (car lst) 1) (meth (cdr lst)))))) 

Est-ce que quelqu'un sait comment faire cela? Merci.

Répondre

2

Vous pouvez simplement utiliser map pour appliquer la fonction cdr à chaque sous-liste de la liste, comme ceci: (map cdr lst). Cependant, cela vous donnera

((((1 1) (2 1))) 
    (((1 3) (5 1))) 
    (((1 4) (7 1))) 
) 

pour votre entrée d'échantillon, qui correspond à un niveau d'imbrication supérieur à votre sortie d'échantillon. Donc, pour obtenir votre sortie de l'échantillon, utilisez list-ref pour obtenir le deuxième élément de chaque sous-liste:

(define (meth lst) (map (lambda (x) (list-ref x 1)) lst)) 

Edit: Comme Eli Barzilay obligeamment a souligné, il y a la fonction cadr pour obtenir le deuxième élément d'une liste, cette peut être raccourci à:

(define (meth lst) (map cadr lst)) 
+0

Notez que 'cadr' renvoie le deuxième élément. (Aussi, c'est une bonne réponse - mais la "modification" dans le texte de la question est fausse.) –

2

Voici une façon de le faire de plus près à ce que vous aviez:

(define meth 
    (lambda (lst) 
    (cond 
     ((null? lst) '()) 
     ((cons (cadr (car lst)) (meth (cdr lst)))) 
    ) 
    ) 
) 


(define a '(
      (#f ((1 1) (2 1))) 
      (#f ((1 3) (5 1))) 
      (#f ((1 4) (7 1))) 
      ))