2009-03-29 11 views

Respuesta

21

Si necesita comparar utilizando uno de los operadores de equivalencia de construcción, puede usar memq, memv, or member, dependiendo de si desea buscar la igualdad usando eq?, eqv?, or equal?, respectivamente.

> (memq 'a '(a b c)) 
'(a b c) 
> (memq 'b '(a b c)) 
'(b c) 
> (memq 'x '(a b c)) 
#f 

Como puede ver, estas funciones devuelven la sublista comenzando en el primer elemento coincidente si encuentran un elemento. Esto se debe a que si está buscando una lista que puede contener booleanos, debe ser capaz de distinguir el caso de encontrar un #f del caso de no encontrar el elemento que está buscando. Una lista es un valor verdadero (el único valor falso en el Esquema es #f) para que pueda utilizar el resultado de memq, memv o member en cualquier contexto esperando un booleano, como una expresión if, cond, and, o or.

> (if (memq 'a '(a b c)) 
    "It's there! :)" 
    "It's not... :(") 
"It's there! :)" 

¿Cuál es la diferencia entre las tres funciones diferentes? Se basa en la función de equivalencia que utilizan para la comparación. eq? (y por lo tanto memq) prueba si dos objetos son el mismo objeto subyacente; es básicamente equivalente a una comparación de puntero (o comparación de valor directo en el caso de enteros). Por lo tanto, dos cadenas o listas que parecen iguales no pueden ser eq?, ya que están almacenadas en diferentes lugares de la memoria. equal? (y por lo tanto member?) realiza una comparación profunda en listas y cadenas, por lo que básicamente dos elementos que impriman lo mismo serán equal?.eqv? es como eq? para casi cualquier cosa menos números; para los números, dos números que son numéricamente equivalentes serán siempre eqv?, pero pueden no ser eq? (esto es debido a bignums y números racionales, que pueden ser almacenados de manera tal que no van a ser eq?)

> (eq? 'a 'a) 
#t 
> (eq? 'a 'b) 
#f 
> (eq? (list 'a 'b 'c) (list 'a 'b 'c)) 
#f 
> (equal? (list 'a 'b 'c) (list 'a 'b 'c)) 
#t 
> (eqv? (+ 1/2 1/3) (+ 1/2 1/3)) 
#t 

(Nótese que algunas comportamiento de las funciones no está definido por la especificación, y por lo tanto pueden diferir de una implementación a otra; he incluido ejemplos que deberían funcionar en cualquier R Esquema RS compatible que implementa el número exacto racionales)

Si necesita buscar un artículo en una lista usando un predicado de equivalencia e diferente de uno de los construidos en los, entonces puede que desee find o find-tail de SRFI-1:

> (find-tail? (lambda (x) (> x 3)) '(1 2 3 4 5 6)) 
'(4 5 6) 
+0

¿Para qué sirve el nombre de la función 'memq'? – Freewind

+1

'memq' es una de las familias de funciones' member', que busca un elemento en una lista basada en algún tipo de equivalencia (como los otros mencionados, 'member' y' memv'). El 'q',' v', o el nombre completo lo conectan con las tres funciones de equivalencia que utilizan; 'memq' usa' eq? 'para probar la equivalencia,' memv' usa 'eqv?' para probar la equivalencia, y 'member' usa' equal? ​​'para probar la equivalencia. Consulte la documentación vinculada sobre las funciones de equivalencia para ver la diferencia entre ellas. –

+0

¡Gracias! Así que 'memq' se puede considerar como' mem-q', y 'memv' como' mem-v' – Freewind

0

Usted está buscando "encontrar"

Básico - El caso más simple es sólo (Encontrar lista de entradas), generalmente utilizados como un predicado: "es la entrada en la lista?". Si logra encontrar el elemento en cuestión, devuelve el primer elemento coincidente en lugar de solo "t". (tomado del segundo enlace.)

http://www.cs.cmu.edu/Groups/AI/html/cltl/clm/node145.html

-o-

http://www.apl.jhu.edu/~hall/Lisp-Notes/Higher-Order.html

+0

La pregunta fue sobre el esquema, no Common Lisp. –

+0

Bueno, etiquetó a LISP. –

+0

Lea el título: '¿Qué es la función SCHEME para encontrar un elemento en una lista?'. Scheme es un dialecto en la familia de lenguajes Lisp. –

3

Aquí hay una manera:

> (cond ((member 'a '(a b c)) '#t) (else '#f)) 
#t 
> (cond ((member 'd '(a b c)) '#t) (else '#f)) 
#f 

miembro vuelve todo a partir de los que el elemento es o #f. Un cond se usa para convertir esto en verdadero o falso.

+0

'# t' está bien también, en lugar de' '# t' –

0

No sé si hay una función integrada, pero se puede crear una:

(define (occurrence x lst) 
     (if (null? lst) 0  
      (if (equal? x (car lst)) (+ 1 (occurrence x (cdr lst))) 
            (occurrence x (cdr lst)) 
      ) 
     ) 
) 

Ỳ obtendrá a cambio el número de ocurrencias de x en la lista. puede ampliarlo con true o false también.

Cuestiones relacionadas