什么是在列表中查找元素的Scheme函数?

8

我有一个元素列表 '(a b c),我想找出其中是否包含(true或false)x,其中x可以是'a或'd,是否有内置函数可实现此功能?


使用语言参考查找:http://schemers.org/Documents/Standards/R5RS//HTML/r5rs-Z-H-9.html#%_sec_6.3.2 - Rainer Joswig
5个回答

26
如果您需要使用内置的等价运算符进行比较,可以使用memqmemvmember,具体取决于您想要使用eq?eqv?equal?来查找相等性。
> (memq 'a '(a b c))
'(a b c)
> (memq 'b '(a b c))
'(b c)
> (memq 'x '(a b c))
#f

如您所见,这些函数会返回子列表,从第一个匹配的元素开始,如果它们找到了一个元素。这是因为,如果您正在搜索可能包含布尔值的列表,则需要能够区分找到#f和未找到要查找的元素的情况。列表是一个真值(Scheme中唯一的假值是#f),因此您可以在任何期望布尔值的上下文中使用memqmemvmember的结果,例如ifcondandor表达式。
> (if (memq 'a '(a b c))
     "It's there! :)"
     "It's not... :(")
"It's there! :)"

这三种不同函数的区别在于它们使用的等价函数进行比较。eq?(因此也包括memq)测试两个对象是否是相同的基础对象;它基本上等同于指针比较(或在整数情况下的直接值比较)。因此,两个看起来相同的字符串或列表可能不是eq?,因为它们存储在内存中的不同位置。equal?(因此也包括member?)对列表和字符串执行深度比较,因此基本上任何打印出相同内容的两个项目都将是equal?。eqv?对于几乎所有内容都类似于eq?,但对于数字而言,两个数值相等的数字始终是eqv?,但它们可能不是eq?(这是由于大数和有理数可能以不会是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

(Note that some behavior of the functions is undefined by the specification, and thus may differ from implementation to implementation; I have included examples that should work in any R5RS compatible Scheme that implements exact rational numbers)
如果您需要使用不同于内置谓词的等价谓词在列表中搜索项目,则可能需要使用 SRFI-1 中的 findfind-tail
> (find-tail? (lambda (x) (> x 3)) '(1 2 3 4 5 6))
'(4 5 6)

memq 函数的名称是什么意思? - Freewind
2
memqmember 函数族中的一个,它根据某种等价关系(与其他函数一样,如 membermemv)在列表中查找项目。qv 或全名将其与它们各自使用的三个等价函数连接起来;memq 使用 eq? 来测试等价性,memv 使用 eqv? 来测试等价性,而 member 使用 equal? 来测试等价性。有关它们之间的区别,请参见等价函数的链接文档。 - Brian Campbell
谢谢!所以 memq 可以被看作是 mem-q,而 memv 可以被看作是 mem-v - Freewind

3
这是一种方法:
> (cond ((member 'a '(a b c)) '#t) (else '#f))
#t
> (cond ((member 'd '(a b c)) '#t) (else '#f))
#f

member从元素开始返回所有内容,或者返回#f。使用cond将其转换为真或假。


#t 可以替换为 '#t - Iulius Curt

0

我不知道是否有内置函数,但您可以创建一个:

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

你将得到列表中 x 出现的次数。你还可以用 true 或者 false 来扩展它。

0

问题是关于Scheme而不是Common Lisp。 - Rainer Joswig
阅读标题:“在列表中查找元素的SCHEME函数是什么?” Scheme是Lisp语言家族中的一个方言。 - Rainer Joswig

0
 (define (member? x list)
     (cond ((null? list) #f)
           ((equal? x (car list)) #t)
           (else   (member? x (cdr list)))))

过程返回 #t(真)或 #f(假)
(member? 10 '(4 2 3))

输出为 #f


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接