gpt4 book ai didi

racket - Racket 的 findf 和 for/first 函数有什么区别?

转载 作者:行者123 更新时间:2023-12-04 07:33:38 26 4
gpt4 key购买 nike

Racket 有findf允许您在列表中查找第一个匹配元素的函数...

(findf even? '(1 2 3 4))
然而,它也有一个 for/first函数,它似乎做同样的事情,尽管语法更复杂......
(for/first ([n '(1 2 3 4)] #:when (even? n)) n)
两者之间有什么区别,鉴于 findf似乎更短,我为什么要使用 for/first ?
谢谢

最佳答案

不同的是for/firstfor 一样迭代,让您拥有 Racket 的全部功能 for 可用的语法:

> (for/first ([i '(1 2 3)]
[j "abc"]
#:when (odd? i)
[k #(#t #f)])
(list i j k))
'(1 #\a #t)
使用 findf 实现相同的效果,您必须预先生成整个列表:
> (findf (λ (x) (odd? (first x)))
(for/list ([i '(1 2 3)]
[j "abc"]
[k #(#t #f)])
(list i j k)))
'(1 #\a #t)
对于搜索单个列表,使用 findf 是正确的。可能是正确的功能。它很简单,可以满足您的需求。但是,如果您想搜索更复杂的列表或需要创建内联列表的列表, for/first更好。

这里有一些更简单的例子,向您展示 for/first 的威力。 (因此 for )。
假设您有两个变量,一个数字列表和一个字母表字符串,您希望将它们一对一配对并返回数字为偶数的第一对。
(define numbers (range 1 27)) ; numbers 1 to 26
(define alphabet "abcdefghijklmnopqrstuvwxyz")
使用 findf ,您需要先将字符串转换为字符列表,然后将两个列表压缩成对,然后创建一个 lambda(匿名函数)来检查给定对是否具有偶数。
(findf (lambda (pair) (even? (first pair)))
(map list numbers (string->list alphabet)))
使用 for/first ,需要为每个序列分配一个标识符,然后引用 #:when中的编号标识符子句来检查数字是否为偶数。 ( for 并行迭代每个序列,在字符串上为您调用 string->list,并且仅在 #:when 返回 true 时才评估主体。)
(for/first ([num numbers]
[str alphabet]
#:when (even? num))
(list num str))
就字符数而言,它们大致相等(94 到 102),但就清晰度而言,我认为 for/first更明显的是它在做什么:取两个集合,同时迭代两个集合,只在数字为偶数时评估主体,并返回一个列表。
如果我们想返回数字为偶数且大于 10 的第一对怎么办?在这里,我们开始看到事情变得笨拙。
(findf (lambda (pair)
(let ([num (first pair)])
(and (even? num)
(> num 10))))
(map list numbers (string->list alphabet)))
相对
(for/first ([num numbers]
[str alphabet]
#:when (even? num)
#:when (> num 10))
(list num str))
;; or
(for/first ([num numbers]
[str alphabet]
#:when (and (even? num)
(> num 10)))
(list num str))
每个 for变体( for/firstfor/list 等)对主体做了一些稍微不同的事情,但迭代逻辑是相同的,允许作者在不重新实现该逻辑的情况下准确表达他们的意图。

关于racket - Racket 的 findf 和 for/first 函数有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67826639/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com