Racket 什么';这是球拍与其他球拍的区别;s findf和for/first函数?

Racket 什么';这是球拍与其他球拍的区别;s findf和for/first函数?,racket,Racket,Racket有一个findf功能,允许您在列表中查找第一个匹配元素 (findf even? '(1 2 3 4)) 但是,它还有一个for/first函数,它似乎也有同样的功能,尽管语法更复杂 (for/first ([n '(1 2 3 4)] #:when (even? n)) n) 两者之间的区别是什么,而且鉴于findf似乎要短得多,为什么我要使用作为/first 谢谢区别在于,for/first像for一样迭代,因此您可以使用球拍语法的全部功能: >(for/first([i'(

Racket有一个
findf
功能,允许您在列表中查找第一个匹配元素

(findf even? '(1 2 3 4))
但是,它还有一个
for/first
函数,它似乎也有同样的功能,尽管语法更复杂

(for/first ([n '(1 2 3 4)] #:when (even? n)) n)
两者之间的区别是什么,而且鉴于
findf
似乎要短得多,为什么我要使用
作为/first


谢谢

区别在于,
for/first
for
一样迭代,因此您可以使用球拍语法的全部功能:

>(for/first([i'(1 2 3)]
[j“abc”]
#:何时(奇数?i)
[k#(#t#f)])
(清单一、j、k)
"(1#\a#t)
要使用
findf
实现同样的效果,您必须提前生成整个列表:

>(findf(λ(x)(奇数)(第一个x)))
(代表/名单([i'(1 2 3)]
[j“abc”]
[k#(#t#f)])
(列表i j k)))
"(1#\a#t)
对于搜索单个列表,使用
findf
可能是正确的函数。它很简单,可以满足你的需要。但是,如果您想在更复杂的列表或需要内联创建的列表中进行搜索,
for/first
更好


下面是一些更简单的示例,向您展示了
for/first
(以及
for
)的强大功能

假设你有两个变量,一个数字列表和一个字母表字符串,你想把它们一一配对,然后返回第一个偶数对

(定义数字(范围127));数字1至26
(定义字母“abcdefghijklmnopqrstuvwxyz”)
使用
findf
,您需要首先将字符串转换为字符列表,然后将两个列表压缩成成对,然后创建一个lambda(匿名函数)来检查给定对是否为偶数

(findf(lambda(对)(偶数)(第一对)))
(地图列表编号(字符串->列表字母表)))
使用
for/first
,您需要将每个序列分配给一个标识符,然后在
#:when
子句中引用数字标识符以检查数字是否为偶数。(
for
并行迭代每个序列,在字符串上为您调用
string->list
,并且仅在
#:when
返回true时计算主体。)

(for/first([num number]
[str字母表]
#:何时(偶数?num))
(列表编号)
就字符数而言,它们大致相等(94到102),但就清晰度而言,我认为/first的
在它所做的工作中更为明显:取两个集合,同时迭代这两个集合,仅在数字相等时计算主体,然后返回一个列表

如果我们想返回第一对,其中的数字是偶数且大于10,该怎么办?在这里,我们开始看到事情变得难以处理

(findf(lambda(对)
(let([num(第一对)])
(和(偶数)
(>num 10)))
(地图列表编号(字符串->列表字母表)))

(for/first([num number]
[str字母表]
#:何时(偶数?num)
#:当(>num 10))
(列表编号)
;; 或
(用于/第一个([数字]
[str字母表]
#:何时(和(偶数?num)
(>num 10)))
(列表编号)

每个
for
变体(
for/first
for/list
,等等)对主体的作用略有不同,但迭代逻辑是相同的,允许作者在不重新实现该逻辑的情况下准确表达其意图。

非常感谢,这非常有用。然而,由于我还是一个球拍的相对初学者,我不太理解你的例子。请你再举一个简单的例子来帮助我理解其中的区别。请留下你已经展示过的那个,因为我相信它会随着时间的推移变得更清晰。再次感谢。我已经用更多的解释和例子更新了答案。我希望他们能帮上忙!祝你好运,这是一种很好的语言。“有用”是一种轻描淡写的说法!这是一个惊人的答案。我希望我能不止一次投票!非常感谢。