在列表中查找元素的Scheme函数是什么? [英] What is the Scheme function to find an element in a list?

查看:104
本文介绍了在列表中查找元素的Scheme函数是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个元素列表'(a b c),并且我想查找其中是否包含x(真或假),例如,x可以是'a或'd.有内置功能吗?

I have a list of elements '(a b c) and I want to find if (true or false) x is in it, where x can be 'a or 'd, for instance. Is there a built in function for this?

推荐答案

如果需要使用等效运算符中的一种进行比较,则可以使用 eq?eqv?equal? .

If you need to compare using one of the build in equivalence operators, you can use memq, memv, or member, depending on whether you want to look for equality using eq?, eqv?, or equal?, respectively.

> (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表达式.

As you can see, these functions return the sublist starting at the first matching element if they find an element. This is because if you are searching a list that may contain booleans, you need to be able to distinguish the case of finding a #f from the case of not finding the element you are looking for. A list is a true value (the only false value in Scheme is #f) so you can use the result of memq, memv, or member in any context expecting a boolean, such as an if, cond, and, or or expression.

> (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?的方式进行存储)

What is the difference between the three different functions? It's based on which equivalence function they use for comparison. eq? (and thus memq) tests if two objects are the same underlying object; it is basically equivalent to a pointer comparison (or direct value comparison in the case of integers). Thus, two strings or lists that look the same may not be eq?, because they are stored in different locations in memory. equal? (and thus member?) performs a deep comparison on lists and strings, and so basically any two items that print the same will be equal?. eqv? is like eq? for almost anything but numbers; for numbers, two numbers that are numerically equivalent will always be eqv?, but they may not be eq? (this is because of bignums and rational numbers, which may be stored in ways such that they won't be 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

(请注意,某些功能的行为未由规范定义,因此实现与实现可能有所不同;我提供了一些示例,这些示例应可在任何实现了R 5 RS兼容方案中使用,有理数)

(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)

如果您需要使用与内置谓词不同的等效谓词搜索列表中的项目,则可能需要 find-tail :

If you need to search for an item in a list using an equivalence predicate different than one of the built in ones, then you may want find or find-tail from SRFI-1:

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

这篇关于在列表中查找元素的Scheme函数是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆