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



我正在构建一个函数,该函数接受一组整数,并返回奇数整数的子集。我遇到了需要跳过地图中的偶数整数的问题,但现在我的函数返回#<void>

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

使用中:

> (oddSubset '(1 2 3))
'(1 #<void> 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)

我假设#!r6rs.fold-rightfilter都在图书馆(rnrs lists (6)) 中。还有SRFI-1,它为R5RS语言提供了这两个过程。

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

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

filter就是您要找的。

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

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

(cond 
   ((odd? x) x))

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

要解决您的问题:请改用filter,因为map将为列表中的每个元素返回一些内容。

如果您想知道如何实现filter,请尝试阅读SICP的第二章

最新更新