在 lambda 映射期间方案跳过或继续

Scheme skip or continue during lambda map

我正在构建一个接受一组整数和 returns 奇数子集的函数。我 运行 遇到了一个问题,我需要跳过我地图中的偶数整数,但现在我的函数 returns #<void> 相反。

 (define (oddSubset set)
   (map
     (lambda (x)
       (cond 
         ((odd? x) x)))
     s))

正在使用:

> (oddSubset '(1 2 3))
'(1 #<void> 3)

我可以像 "else, continue onto next element" 一样使用逻辑吗?

注意:我正在尝试重写内置的过滤器功能

map 看起来是个奇怪的选择。根据定义,它将函数映射到列表中的每个元素和 returns 结果列表,因此尝试 "skip" 元素似乎不自然。

filter 就是您要找的。

(filter odd? '(1 2 3))
'(1 3)

map没有跳过的可能,但是可以用filter代替:

(filter odd? '(1 2 3 4 5 6)) ; ==> (1 3 5)

或者您可以使用 fold-right

(fold-right (lambda (e acc)
              (if (odd? e)
                  (cons e acc)
                  acc))
            '()
            '(1 2 3 4 5 6)) ; ==> (1 3 5)

我假设 #!r6rsfold-rightfilter 都在图书馆 (rnrs lists (6)) 中。还有 SRFI-1 给出了 R5RS 语言的这两个过程。

在 none 标准语言中 #!racket 使用名称 foldr 代替 fold-right

map 对所有元素应用函数。函数的每次调用都应该独立于其他调用。即使你引入一个带有闭包的状态,你也无法避免 map 构建一个与你的输入相同大小的列表。 您想要(重新)实现 filter 函数。如果你想自己做,你应该尝试使用 foldlfoldr 来代替。

(cond 
   ((odd? x) x))

map 检查列表中的每个元素:如果是奇数,则 return 该元素。但是你没有告诉你的程序当元素不是奇数时要做什么,所以map return void

要解决您的问题:请改用 filter,因为 map 会 return 列表中的每个元素。

如果你想知道如何实现filter,请尝试阅读SICP

的第二章