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

标签 lisp scheme

我有一个元素列表 '(a b c),我想找出其中是否有(真或假)x,例如,其中 x 可以是 'a 或 'd。是否有内置函数?

最佳答案

如果您需要使用内置等价运算符之一进行比较,您可以使用 memq, memv, or member , 取决于你是否想使用 eq?, eqv?, or equal? 寻找平等, 分别。

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

如您所见,如果找到元素,这些函数将返回从第一个匹配元素开始的子列表。这是因为如果您正在搜索可能包含 bool 值的列表,您需要能够区分找到 #f 的情况和没有找到您要查找的元素的情况。列表是真值(Scheme 中唯一的假值是#f),因此您可以使用memqmemvmember 在任何需要 bool 值的上下文中,例如 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?(这是因为 bignums 和有理数,可以存储以这样的方式,他们不会 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

(请注意,函数的某些行为未由规范定义,因此可能因实现而异;我已经包含了应该在任何 R5RS 兼容方案中工作的示例,这些方案实现了精确的有理数)

如果您需要使用不同于内置谓词之一的等价谓词在列表中搜索项目,那么您可能需要 findfind-tail来自 SRFI-1:

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

关于lisp - 在列表中查找元素的 Scheme 函数是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/694669/

相关文章:

lisp - 如何在 LISP 中获取模数

lisp - 按位置获取列表元素

列表的 lisp Cons 单元图

scheme - LISP 中以索引作为参数之一的映射函数

scheme - 如何在方案中使用foldr?

方案:不使用 if/cond 解决任务?

scheme - DrRacket : atom? 和符号? undefined - 怎么了?

lisp - common lisp sbcl 手册 ffi 示例失败

scheme - 为什么 "eq?"在以下上下文中评估为 false 而在其他情况下评估为 true?

linux - 如何安装 dorodango 包管理器 Scheme 语言